Java 如何在不使用foreach的情况下合并两个列表?
最初,我有以下代码:Java 如何在不使用foreach的情况下合并两个列表?,java,list,collections,Java,List,Collections,最初,我有以下代码: String[] A; String[] B; //... List<String> myList= new ArrayList<>(A.length + B.length); for (int i= 0; i< B.length; i++){ myList.add(A[i]); myList.add("*".equals(B[i]) ? B[i] : doSomethingWith(B[i])); } String[]A; 字符
String[] A;
String[] B;
//...
List<String> myList= new ArrayList<>(A.length + B.length);
for (int i= 0; i< B.length; i++){
myList.add(A[i]);
myList.add("*".equals(B[i]) ? B[i] : doSomethingWith(B[i]));
}
String[]A;
字符串[]B;
//...
列表myList=新的ArrayList(A.length+B.length);
for(int i=0;i
如果最好使用Java8,如何重构
例如,如果我有这些数组
A={“一”、“二”、“三”、“四”}
B={“五”、“六”、“七”、“八”}
在代码末尾,myList将是:
myList={“一”、“五”、“二”、“六”、“三”、“七”、“四”、“八”}我个人认为这不需要重构,因为任何“流式”代码的可读性和直观性都不如您现有的代码,但作为纯粹的概念证明:
String[] A;
String[] B;
List<String> myList;
myList = IntStream.range(0, B.length)
.mapToObj(i -> new String[]
{
A[i],
"*".equals(B[i]) ? B[i] : doSomethingWith(B[i])
})
.flatMap(Arrays::stream)
.collect(Collectors.toList());
String[]A;
字符串[]B;
列出我的清单;
myList=IntStream.range(0,B.length)
.mapToObj(i->新字符串[]
{
A[我],
“*”.equals(B[i])?B[i]:doSomethingWith(B[i])
})
.flatMap(数组::流)
.collect(Collectors.toList());
- 我们使用
为数组提供索引IntStream.range
将每个索引映射到一个包含我们想要的元素的数组(这个阶段也是需要的,因为mapToObj
只能转换为另一个IntStream::flatMap
,我们想将它转换为IntStream
字符串的
)流
将每个数组映射到一个流,然后“展平”生成的流flatMap
- 最后,我们只是收集结果
String[] A;
String[] B;
//...
List<String> myList= Arrays.asList (A);
List<String> myList2 = Arrays.stream(B).map(
(x)->"*".equals(x) ? x : doSomethingWith(x))
.collect(Collectors.toList());
myList.addAll(myList2);
String[]A;
字符串[]B;
//...
List myList=Arrays.asList(A);
列表myList2=Arrays.stream(B).map(
(x) ->“*”。等于(x)?x:doSomethingWith(x))
.collect(Collectors.toList());
myList.addAll(myList2);
为什么不使用foreach?我不会说这需要重构-它的作用已经很清楚了,尝试将其封装在某种流中可能会使其更难遵循。@Raullaves顺便说一句,您现在没有使用实际的foreach
循环,可能使用两个迭代器而不是循环索引?但我真的不认为代码有问题。如果SonarQube抱怨,就告诉它忽略它。事实上,就我个人而言,我看不出需要streams/Java8解决方案来解决所有问题,因为它只会降低代码的可读性(在我看来)。这正是我想要的。非常感谢你!你可以提高可读性——我尝试了一下,但被拒绝了;然而,流媒体的好处超出了可读性。OPs解决方案必须进行“全阵列扫描”,而流式解决方案可以延迟评估,元素可以跳过(并且计算,例如,doSomethingWith
将不会在跳过的元素上发生),最后,所有这些都可以并行化,这在OPs情况下会更加困难,并会导致共享,可能有争议的记忆access@diginoise我试图刻意模仿OP的部分结构——不过我很欣赏使用Arrays::stream
进行编辑。使用newarraylist(A.length+B.length)
初始化myList
没有任何意义;无论如何,它都将被流操作的无关结果覆盖。进一步,您可以将其简化为.mapToObj(i->Stream.of(A[i],“*”).equals(B[i])?B[i]:doSomethingWith(B[i])).flatMap(Function.identity())