Java 功能集合和未检查的警告

标签 java generics compiler-warnings type-erasure

我写了一个纯函数集合类——一个包,又名 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/

相关文章:

generics - 特征对象如何使用通用方法作为参数来接受特征?

objective-c - 不兼容的指针类型警告(在 Objective-C 中)

java - list 合并因多个错误而失败,请参阅日志(错误 :Execution failed for task ':app:processDebugManifest' )

java - Objective-C 中的等效 Java javax.crypto 库?

java - SortableTable的自定义排序

java - 设计 Java 通用层次结构以避免模板类冲突

java - 在程序结束时将静态对象的内容写入磁盘

c# - 索引器继承在泛型中如何工作?

c++ - 使用 GCC 强制执行显式(直接)#include 语句

cocoa - 避免 "[superclass] may not respond to [selector]"警告,而不会引发 LLVM 的 "Cannot cast ' super'"错误