简体   繁体   中英

Java 8 nested streams - convert chained for loops

I'm currently playing around with Java 8 features .

I have the following piece of code, and tried out multiple ways to use Stream s, but without success.

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.

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.

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:

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 :

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

You should prefer collect over forEach when your goal is to produce some output Collection :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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