Home > Enterprise >  java 8 stream for double loop and change the value in first loop
java 8 stream for double loop and change the value in first loop

Time:05-13

i have nested loop to loop and change the first list based on condition below. this works fine.

its like if cardNumber in firstList same or found in secondList, copy properties from secondList to firstList.

for (int i = 0; i < listFirst.size(); i  ) {
    for (int j = 0; j < listSecond.size(); j  ) {
        if (StringUtils.equals(listFirst.get(i).getCardNumber(), listSecond.get(j).getCardNumber())) {
            try {
                 listFirst.get(i).setSubmitDate(listSecond.get(j).getIssueDate());
                 listFirst.get(i).setPersonalNumber(listSecond.get(j).getPersonalNumber());
                 listFirst.get(i).setMembershipPeriod(listSecond.get(j).getPeriod());
                 listFirst.get(i).setPhoneNumber(listSecond.get(j).getMobileNo());
                 listFirst.get(i).setIdCardNumber(listSecond.get(j).getIdNumber());
                 listFirst.get(i).setMoney(listSecond.get(j).getLoanAmount().toString());
                } catch (Exception e) {
                    log.error(e.getMessage());
                }
        }
    }
}

i just want to know is this possible in java 8 stream? or lambda expression? i've tried using stream, for each, but sometimes i got confused.

CodePudding user response:

With a little reorganization, yes:

If you were to add a method to the class in the first list to do the checks and assignments:

public void init(YourClass other) {
    if (StringUtils.equals(getCardNumber(), other.getCardNumber())) {
        try {
             setSubmitDate(other.getIssueDate());
             setPersonalNumber(other.getPersonalNumber());
             setMembershipPeriod(other.getPeriod());
             setPhoneNumber(other.getMobileNo());
             setIdCardNumber(other.getIdNumber());
             setMoney(other.getLoanAmount().toString());
         } catch (Exception e) {
             log.error(e.getMessage());
         }
    }
}

Then your loop can become:

listFirst.stream()
         .forEach(a -> listSecond.stream()
                                 .forEach(b -> a.init(b)));

CodePudding user response:

Assuming that Foo is your class, we can form a cartesian product of items of the 2 lists, and then filter by some property (cardNumber equality). Then, matching pairs can be used in a forEach stream-terminating method.

listFirst.stream()
   .flatMap(t -> listSecond.stream().map(s -> new Foo[] {t, s}))
   .filter(pair -> StringUtils.equals(pair[0].getCardNumber(), pair[1].getCardNumber()))
   .forEach(pair -> {
       final Foo t = pair[0], s = pair[1]; // unpack pair
       // set individual properties here (or call a setup method) ...
       t.setSubmitDate(s.getIssueDate())
       // .... more sets ...
   }) 
  • Related