在我的代码中的几个位置,我有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
。
我该怎么做?
答案 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图书馆的代码。