Home > Software design >  how to join two List of different signature type with a common property using Java stream()?
how to join two List of different signature type with a common property using Java stream()?

Time:02-24

class ScannedCoupon{
    Long id;
    String scannedcode;
}
        
class WinnerCoupon{
    Long id;
    String winnercode;
    boolean won;
}
    
List<ScannedCoupon> scannedCouponList;
List<WinnerCoupon> winnerCouponList;

Here are my cases:

I do have two lists scannedCouponList with 30 items and winnerCouponList with 200. one them is code scanned by users and other is the list of winner. I want to update winnerCouponList if any of the ScannedCoupon's scannedcode is inside winnerCouponList.

is there any way to update the won property to true from winnerCouponList if any of the winnercode == scannedcode from scannedCouponList using java stream() ?

I do not want to use loops over and over again for 200 WinnerCoupon if any one of them is in scannedCouponList or not.

CodePudding user response:

First you can collect the scanned codes to a Set.

Set<String> scannedCodes = scannedCouponList.stream()
                                            .map(ScannedCoupon::getScannedCode)
                                            .collect(Collectors.toSet());

The above set helps to avoid looping the scanned list for each winner coupon as Set.contains has O(1) time complexity. Now, stream the winner coupon list and check if the code is available in scannedCodes:

winnerCouponList.stream()
                .filter(coupon -> scannedCodes.contains(coupon.getWinnerCode()))
                .forEach(coupon -> coupon.setWon(true));

Since the winner list size is much more than your scanned list, this would have approximately O(n) time complexity (considering the size of scanned list is very small compared to winner list) where n is size of winner list.

CodePudding user response:

We loop around on winnerCouponList and at the same time for each winnerCoupon we check in scannedCoupon list have scannedCode == winnerCode. If yes, then we update the winnerCoupon.won = true. If no, we will continue in our loop until we found scannedCode == winnerCode or we reach the end of scannedCouponList

winnerCouponList.stream()
   .forEach(winnerCoupon -> {
       scannedCouponList.stream()
       .filter(scannedCoupon -> {
           return scannedCoupon.scannedcode.equals(winnerCoupon.winnercode);
       })
       .limit(1)
       .forEach(scannedCoupon -> winnerCoupon.won = true);
   });
  • Related