2013-05-25 146 views
3

我必须不断写出比我想要的更长的代码,而且我必须做很多次。通过一个集合调用方法添加到另一个集合

Collection<MiClase> collection1 = new ArrayList<MiClase>; 
Collection<String> collection2 = new ArrayList<String>; 
// I currently do this 
for (MiClase c : collection1){ 
    collection2.add(c.nombre()); // nombre() returns String 
} 

有什么可以缩短它吗?

// I want something like 
collection2.addAll(collection1, MiClase.nombre); 

谢谢!!!

+0

类型的对象,如果这样的事情存在它会在JavaDoc中,而它不是:(。所以,不幸的是,如果你不想采纳Dukeling关于反思的评论,你就会被困在你目前正在做的事情中。 – greedybuddha

回答

5

有没有内置的java函数来做那个¹。你可以使用番石榴“Collections2#transform(collection, function)

所以,你的代码将看起来像

// nombres = collections2, miClasses = collection1 
nombres.addAll(Collections2.transform(miClasses, new Function() { 
    @Override 
    public String apply (MiClasse miClasse) { 
     return miClasse.nombre(); 
    } 
})); 

但这真是麻烦,可能是矫枉过正,只删除一个简单的循环。

编辑

1 - 正如A.R.S.指出,没有内置Java 8 Lambda表达式和改进收集API之前。有一些很酷的例子链接:http://www.javabeat.net/2012/05/enhanced-collections-api-in-java-8-supports-lambda-expressions/

+1

Java不支持lambda表达式(或者至少在Java 8之前不会)使得这非常麻烦,因为我们只需要为单个方法扩展/实例化一个类(它就像通过伪造lambda函数匿名类)。无论如何,我建议坚持循环。 – arshajii

+0

@ A.R.S。是的,完全同意。我正在寻找带有lambda表达式和改进的JVM装箱/拆箱的Java 8。 –

+0

我想要这个!所以我需要等到新的Java :( – leftsync

2

更多的完整性比什么都重要......

你可以写做此方法使用reflection

static <A,B> void addAll(Collection<B> dest, Collection<A> source, String methodName) 
     throws IllegalAccessException, InvocationTargetException, NoSuchMethodException 
{ 
    for (A a: source) 
    { 
    // can optimize this to only get method once if all objects have same type 
    Method m = a.getClass().getMethod(methodName); 
    dest.add((B)m.invoke(a)); 
    } 
} 

使用/例如:

ArrayList<String> s = new ArrayList<String>(); 
List<Integer> i = Arrays.asList(1,2,3); 
addAll(s, i, "toString"); 
System.out.println(s); 

如果您愿意,还可以添加方法参数。

Test

为什么我会>>没有< <推荐它

如果抛出异常3不必担心,你还......(当然,你可以try - catch,而是完全避免例外)

(人)的故障的几点:(这些都将显示为运行时错误,但编译时错误是优选的)

  • N的方法AME被拼错
  • 的方法根本不存在
  • 该方法不返回B
相关问题