我写了一个纯函数集合类——一个包,又名 multiset——它工作正常,但在类定义本身和使用中,特别是在和使用 FBag 时,会为未经检查的赋值生成许多警告.制作
。据我所知,问题主要源于函数集合需要静态工厂方法而不是公共(public)构造函数,而静态方法无法访问泛型类型。
有没有一种优雅的方法可以避免这种情况,还是我必须硬着头皮接受这是一个类型删除问题,然后抑制警告?
代码如下。 (我知道此实现渐近效率低下。预计 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;
}
}
}
最佳答案
对于 static
成员 EMPTY
,我相信没有办法绕过使用原始类型。您可以在 Collections.EMPTY_LIST
中看到相同的内容:
@SuppressWarnings("rawtypes")
public static final List EMPTY_LIST = new EmptyList<>();
@SuppressWarnings("unchecked")
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
因此,您在这里所能做的就是取消警告:
@SuppressWarnings("rawtypes")
public static final FBag EMPTY = new FBag<>(null, null);
@SuppressWarnings("unchecked")
public static final <T> FBag<T> empty() {
return (FBag<T>) EMPTY;
}
另一方面,对于 static
方法,您可以声明它们自己的通用类型变量。
public static <E> FBag<E> make(Collection<E> c) {
FBag<E> p = empty ();
for (E a : c) {
p = p.add(a);
}
return p;
}
public static <E> FBag<E> make(E[] c, int from, int to) {
FBag<E> p = empty ();
for (int i = from; i < to; i++) {
p = p.add(c[i]);
}
return p;
}
(我用显式声明替换了 var
,因为我没有安装 Java 10,而且我不想发布未经检查的代码)。
关于Java 功能集合和未检查的警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53977290/