将List <mydatatype>转换为List <string> </string> </mydatatype>的更好方法

时间:2012-12-04 14:26:15

标签: java

我想知道是否没有更好的方法来转换整个ListsCollections,就像我在以下代码示例中显示的那样:

public static List<String> getAllNames(List<Account> allAccounts) {
        List<String> names = new ArrayList<String>(allAccounts.size());
        for (Account account : allAccounts) {
            names.add(account.getName());
        }
        return names;
    }

每当我产生这样的method时,我开始思考,是不是有更好的方法?我的第一个想法是创建一个可能有一些genericsreflections的解决方案,但这似乎有点过大,在性能方面可能有点慢?

6 个答案:

答案 0 :(得分:6)

查看Google的Guava图书馆

这样的事情应该这样做

final List<String> names = Lists.transform(myObjs, new Function<MyObject, String>() {
    public String apply(final MyObject input) {
        return input.getName();
    }
});

答案 1 :(得分:5)

使用Guava,有一种更实用的方法:

return FluentIterable.from(allAccounts).transform(new Function<Account,String>(){
    public String apply(Account account){return account.getName();}
}).toImmutableList()

但当然,这基本上也是一样的。

BTW:这个答案和RNJ之间的区别在于,在我的情况下,列表将被创建一次,而在另一个答案中,它是一个实时视图。两个版本都有效,但适用于不同的场景。

答案 2 :(得分:2)

我的个人图书馆实际上有这种方法。

public static <TSource,TTarget> List<TTarget> castList(List<TSource> sourceList)
{
    List<TTarget> targetList = new ArrayList<TTarget>(sourceList.size());
    for (TSource t : sourceList) {
        //This will throw a ClassCastException if the types are not compatible
        //Be carefull
        targetList.add((TTarget)t);
    }
    return targetList;
}

用法非常简单,因为编译器会推断出TTarget的类型。

List<Object> objects = new ArrayList<Object>();
objects.add("One");
objects.add("Two");

List<String> strings = castList(objects);

关于表现: 我认为使用泛型在这里没问题。但复制整个阵列的需要是另一回事。

答案 3 :(得分:0)

没有更好的方法。铸造是一件困难而且危险的事情。在您的示例中,您无法将String转换为MyDataType,反之亦然,不是吗? 你可以使用某种toStringList()创建一个自己的List-Implementation - 如果你需要更频繁的话,可以使用方法。

答案 4 :(得分:0)

有一种简单的方法,但它不是类型安全的

List<A> a = new ArrayList<A>();
List<B> b = (List)a;

但是你必须覆盖类的toString()方法的实现以返回getName()值。 但是没有类型检查,

如上所述,您当然可以改为循环并在每个对象上调用getName

答案 5 :(得分:0)

您可以尝试使用Guava库中的IterablesFunction类。您可以使用

创建Iterable的新类型
Iterable<String> newTypeIterable = Iterables.transform(oldTypeIterable, new Function<MyDataType, String> () {
   @Override
   public String apply(MyDataType from)
   {
     return from.getName();
   }
});

事实证明,您也可以使用Lists课程执行此操作!