gpt4 book ai didi

java - 将对集合中的元素运行方法的所有结果添加到另一个集合

转载 作者:行者123 更新时间:2023-12-01 08:14:58 25 4
gpt4 key购买 nike

有没有 lambdaj 方法可以巧妙地做到这一点?我知道标题听起来很复杂,但下面的代码片段应该可以清楚地说明:

private List<String[]> getContractLineItemsForDatatables(List<ContractLineItem> contractLineItems) {

List<String[]> contractLineItemsForDatatables = Lists.newArrayList();

for (ContractLineItem contractLineItem : contractLineItems) {

contractLineItemsForDatatables.add( contractLineItem.getDataTablesRow());
}

return contractLineItemsForDatatables;
}

必须有一种巧妙的方法可以使用 Lambdaj 来避免上面的 for 循环,但我无法理解它。顺便说一句,contractLineItem.getDatatablesRow() 返回一个 String[]。

所以我想做的是:

对contractLineItems列表中的所有元素运行getDataTablesRow(),并将它们添加到contactLineItemsForDatatables列表中。

有什么建议吗?

最佳答案

大部分冗长的内容来自于变量名的选择,而不是 Java 代码。

private static List<String[]> extractDataTableRows(List<ContractLineItem> items) {
List<String[]> ret = new ArrayList<>();
for (ContractLineItem item : items) ret.add(item.getDataTablesRow());
return ret;
}

如果抛出异常,它看起来像

Exception in thread "main" java.lang.RuntimeException
at Main$ContractLineItem.getDataTablesRow(Main.java:87)
at Main.extractDataTableRows(Main.java:50)
at Main.main(Main.java:27)

使用 Guava 的 lambda

private static List<String[]> extractDataTableRows(List<ContractLineItem> items) {
return Lists.transform(items, new Function<ContractLineItem, String[]>() {
@Override
public String[] apply(ContractLineItem item) {
return item.getDataTablesRow();
}
});
}

如果抛出异常,它看起来像

Exception in thread "main" java.lang.RuntimeException
at Main$ContractLineItem.getDataTablesRow(Main.java:76)
at Main$1.apply(Main.java:38)
at Main$1.apply(Main.java:35)
at com.google.common.collect.Lists$TransformingRandomAccessList.get(Lists.java:495)
at java.util.AbstractList$Itr.next(AbstractList.java:358)
at java.util.AbstractCollection.toString(AbstractCollection.java:459)
at java.lang.String.valueOf(String.java:2957)
at java.io.PrintStream.println(PrintStream.java:821)
at Main.main(Main.java:31)

注意:只有使用 List 才会触发异常。

这个Guava Caveat对我来说已经很清楚了。

As of Java 7, functional programming in Java can only be approximated through awkward and verbose use of anonymous classes. This is expected to change in Java 8, but Guava is currently aimed at users of Java 5 and above.

Excessive use of Guava's functional programming idioms can lead to verbose, confusing, unreadable, and inefficient code. These are by far the most easily (and most commonly) abused parts of Guava, and when you go to preposterous lengths to make your code "a one-liner," the Guava team weeps.

使用 Java 8。

private static List<String[]> extractDataTableRows(List<ContractLineItem> items) {
return items.stream()
.<String[]>map(ContractLineItem::getDataTablesRow)
.into(new ArrayList<>());
}

添加您可以编写的实用方法

public static <E, R> List<R> map(Collection<E> elements, Function<? super E, ? extends R> function) {
return elements.stream().<R>map(function).into(new ArrayList<R>());
}

// hiding the guff, this is more readable IMHO.
private static List<String[]> extractDataTableRows(List<ContractLineItem> items) {
return map(items, ContractLineItem::getDataTablesRow);
}

如果抛出异常,它可能看起来像这样

 Exception in thread "main" java.lang.RuntimeException
at Main$ContractLineItem.getDataTablesRow(Main.java:77)
at Main$$Lambda$1.apply(Unknown Source)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:87)
at java.util.Arrays$ArraySpliterator.forEach(Arrays.java:4551)
at java.util.stream.AbstractPipeline$PipelineHelperImpl.into(AbstractPipeline.java:197)
at java.util.stream.op.ForEachOp.evaluateSequential(ForEachOp.java:86)
at java.util.stream.op.ForEachOp.evaluateSequential(ForEachOp.java:37)
at java.util.stream.AbstractPipeline.pipeline(AbstractPipeline.java:336)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:142)
at java.util.Collection.addAll(Collection.java:505)
at java.util.ArrayList.addAll(ArrayList.java)
at java.util.stream.ReferencePipeline.into(ReferencePipeline.java:189)
at Main.map(Main.java:34)
at Main.extractDataTableRows(Main.java:39)
at Main.main(Main.java:29)
<小时/>

虽然@Edwin的答案最短,但它是最难调试和维护的,因为要实现这一点需要分配“魔法”。这对于单元测试来说很好,但恕我直言,您不希望它出现在生产代码中。

 Exception in thread "main" ch.lambdaj.function.argument.InvocationException: Failed invocation of public java.lang.String[] Main$ContractLineItem.getDataTablesRow() on object Main$ContractLineItem@1d724f31 caused by: null
at ch.lambdaj.function.argument.Invocation.invokeOn(Invocation.java:70)
at ch.lambdaj.function.argument.InvocationSequence.invokeOn(InvocationSequence.java:91)
at ch.lambdaj.function.argument.InvocationSequence.invokeOn(InvocationSequence.java:85)
at ch.lambdaj.function.argument.Argument.evaluate(Argument.java:35)
at ch.lambdaj.function.convert.ArgumentConverter.convert(ArgumentConverter.java:36)
at ch.lambdaj.function.convert.ConverterIterator.next(ConverterIterator.java:37)
at ch.lambdaj.Lambda.convert(Lambda.java:986)
at ch.lambdaj.Lambda.extract(Lambda.java:1035)
at Main.extractDataTableRows(Main.java:49)
at Main.main(Main.java:27)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:474)
at ch.lambdaj.function.argument.Invocation.invokeOn(Invocation.java:68)
... 14 more
Caused by: java.lang.RuntimeException
at Main$ContractLineItem.getDataTablesRow(Main.java:85)
... 19 more

这种语法需要一些时间来使用,但我想当他们收紧语法并删除一些样板代码时,它可能会更具可读性。

这是一个很好的比较 Java 8 Lambda vs LambdaJ vs Guava vs Iterative approach原文为俄语,请原谅谷歌翻译;)

关于java - 将对集合中的元素运行方法的所有结果添加到另一个集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14234546/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com