Я написал чисто функциональный класс коллекции - bag aka multiset - и он отлично работает, но генерирует ряд предупреждений для непроверенного назначения, как в самом определении класса, так и при использовании, особенно при использовании FBag.make
.Насколько я вижу, проблема возникает в первую очередь из-за того, что функциональные коллекции хотят использовать статические фабричные методы вместо открытых конструкторов, а статические методы не могут получить доступ к универсальному типу.
Существует ли элегантный способ избежать этого,или мне просто нужно прикусить пулю, признать, что это проблема стирания типа, и подавить предупреждения?
Код следует.(Я знаю, что эта реализация асимптотически неэффективна. Ожидается, что N будет небольшим; если это изменится, я изменю реализацию.)
import java.util.Collection;
import java.util.Iterator;
public class FBag<E> implements Iterable<E> {
public static final FBag EMPTY = new FBag<>(null, null);
private final FBag<E> next;
private final E val;
private FBag(E val, FBag<E> next) {
this.val = val;
this.next = next;
}
public FBag<E> add(E val) {
return new FBag<>(val, this);
}
@Override
public Iterator<E> iterator() {
return new Iter<>(this);
}
public static FBag make(Collection c) {
var p = EMPTY;
for (var a : c) {
p = p.add(a);
}
return p;
}
public static FBag make(Object[] c, int from, int to) {
var p = EMPTY;
for (var i = from; i < to; i++) {
p = p.add(c[i]);
}
return p;
}
public FBag<E> remove(E val) {
if (this == EMPTY) {
return this;
}
if (this.val == val) {
return next;
}
return new FBag<>(this.val, next.remove(val));
}
private static class Iter<E1> implements Iterator {
private FBag<E1> p;
Iter(FBag<E1> p) {
this.p = p;
}
@Override
public boolean hasNext() {
return p != EMPTY;
}
@Override
public Object next() {
assert p != EMPTY;
var r = p.val;
p = p.next;
return r;
}
}
}