我必须继续编写比我想要的更长的代码,而且我必须做很多次。
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 :(得分:5)
没有内置的java函数可以做到这一点¹。你可以使用Guavas'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 :(得分: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);
如果您愿意,也可以添加方法参数。
为什么我会&gt;&gt; NOT&lt;&lt;推荐:
如果抛出3个例外并不让你担心......(当然,你可以try
- catch
,而是完全避免例外)
(人类)失败的几点:(这些都将显示为运行时错误,但首选编译时错误)
B
答案 2 :(得分:0)
使用Stream API
的几种方法中的两种:
对于
Collection<MiClase> collection1 = new ArrayList<>;
Collection<String> collection2 = new ArrayList<>;
MiClase#nombre
返回String
作为OP提到:
collection1.stream()
.map(MiClase::nombre)
.collect(Collectors.toList())
.forEach(collection2::add);
或
collection2.addAll(collection1.stream()
.map(MiClase::nombre)
.collect(Collectors.toList()));