在Java中转换泛型Collection的类型

时间:2015-05-14 09:51:52

标签: java generics collections

在我的代码中的几个位置,我有ArrayLists和TreeSets,我希望转换它们的泛型类型。例如,我有ArrayList<Integer>我想转换为ArrayList<Long>。或者我有TreeSet<BigInteger>我想转换为TreeSet<String>

所有这些转换都可以进行,但是我必须为每个类型转换创建一个不同的函数。因此,我想创建一个通用函数,其签名如下所示:

public static <Q,T> Collection<Q> convert(Collection<T> col, Class<Q> Q)

我想要的是从col获取课程(例如ArrayList),创建该课程的新集合并输入Q(称为newCol),以及然后遍历col并将T类型的每个元素转换为Q类型,并将其添加到newCol,最后返回newCol

我该怎么做?

2 个答案:

答案 0 :(得分:1)

没有特殊的机制,比如在Java中转换不兼容的类。您需要指定一个将执行转换的显式函数。使用Java 8非常简单:

public static <Q,T,C extends Collection<Q>> C convert(Collection<T> col, Function<T, Q> fn, 
                   Supplier<C> supplier) {
    return col.stream().map(fn).collect(Collectors.toCollection(supplier));
}

像这样使用:

TreeSet<BigInteger> values = // fill them somehow
TreeSet<String> converted = convert(values, BigInteger::toString, TreeSet::new);

答案 1 :(得分:0)

@Tagir Valeev 是对的。您可以在Java 8中轻松完成。但是如果您使用Java 7,您可以尝试执行以下操作:

    public static <F, T> Collection<T> transform(Collection<F> fromCollection, Function<? super F, T> function) {
        return new TransformedCollection<F, T>(fromCollection, function);
    }

    static class TransformedCollection<F, T> extends AbstractCollection<T> {
        final Collection<F> fromCollection;
        final Function<? super F, ? extends T> function;

        TransformedCollection(Collection<F> fromCollection, Function<? super F, ? extends T> function) {
            this.fromCollection = checkNotNull(fromCollection);
            this.function = checkNotNull(function);
        }

        @Override public void clear() {
            fromCollection.clear();
        }

        @Override public boolean isEmpty() {
            return fromCollection.isEmpty();
        }

        @Override public Iterator<T> iterator() {
            return Iterators.transform(fromCollection.iterator(), function);
        }

        @Override public int size() {
            return fromCollection.size();
        }
    }

来自Guava图书馆的代码。