简体   繁体   English

Java 8嵌套流-转换链式循环

[英]Java 8 nested streams - convert chained for loops

I'm currently playing around with Java 8 features . 我目前正在使用Java 8功能。

I have the following piece of code, and tried out multiple ways to use Stream s, but without success. 我有以下代码,并尝试了多种使用Stream的方法,但没有成功。

for (CheckBox checkBox : checkBoxList) {
   for (String buttonFunction : buttonFunctionsList) {
      if (checkBox.getId().equals(buttonFunction)) {
          associatedCheckBoxList.add(checkBox);
      }
   }
}

I tried the following, but I am not sure is this correct or not: 我尝试了以下操作,但不确定是否正确:

checkBoxList.forEach(checkBox -> {
     buttonFunctionsList.forEach(buttonFunction -> {
     if (checkBox.getId().equals(buttonFunction))
     associatedCheckBoxList.add(checkBox);
     });
     });

Thanks! 谢谢!

Eran's answer is probably fine; 伊兰的答案可能还不错。 but since buttonFunctionList is (presumably) a List, there is a possibility of it containing duplicate elements, meaning that the original code would add the checkboxes to the associated list multiple times. 但是由于buttonFunctionList是(大概是)一个List,所以它可能包含重复的元素,这意味着原始代码会将复选框多次添加到关联的列表中。

So here is an alternative approach: you are adding the checkbox to the list as many times as there are occurrences of that item's id in the other list. 因此,这是另一种方法:将复选框添加到列表的次数与另一个列表中该项目ID的出现次数相同。

As such, you can write the inner loop as: 这样,您可以将内部循环编写为:

int n = Collections.frequency(buttonFunctionList, checkBox.getId();
associatedCheckboxList.addAll(Collections.nCopies(checkBox, n);

Thus, you can write this as: 因此,您可以这样写:

List<CheckBox> associatedCheckBoxList =
    checkBoxList.flatMap(cb -> nCopies(cb, frequency(buttonFunctionList, cb.getId())).stream())
        .collect(toList());

(Using static imports for brevity) (为简洁起见,请使用静态导入)

If either checkBoxList or buttonFunctionList is large, you might want to consider computing the frequencies once: 如果checkBoxListbuttonFunctionList很大,则可能需要考虑一次计算频率:

Map<String, Long> frequencies = buttonFunctionList.stream().collect(groupingBy(k -> k, counting());

Then you can just use this in the lambda as the n parameter of nCopies : 然后,您可以在lambda中将其用作nCopiesn参数:

(int) frequencies.getOrDefault(cb.getId(), 0L)

You should prefer collect over forEach when your goal is to produce some output Collection : 当您的目标是产生一些输出Collection时,您应该首选collect forEach

List<CheckBox> associatedCheckBoxList =
    checkBoxList.stream()
                .filter(cb -> buttonFunctionsList.stream().anyMatch(bf -> cb.getId().equals(bf)))
                .collect(Collectors.toList());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM