Update objects in one list based on values from second one using streams

modify property value of the objects in list using java 8 streams
how to get values from list object in java 8
java 8 compare two lists of objects
java 8 filter list based on another list
java-stream find all matches
java 8 filter list of objects by property
java stream filter two lists
java 8 compare 2 lists based on one property

I have two corresponding lists:

public class BookOverallData {
    private Long idOfBook;
    private String title;
    private String authour;
    private BigDecimal basePrice;
    private Integer discountRate;
}

public class TimeDiscount {    
    private Long idOfBook;
    private Integer discountRate;    
}

Set<BookOverallData> booksToReturn
Set<TimeDiscount> actualPromotions

The goal is to sum discounts, which means adding discountRate from actualPromotions to discountRate value from the booksToReturn list. The objects from both lists can be matched by idOfBook.

This is how I solved it

booksToReturn.forEach(
            p -> {
                final Optional<TimeDiscount> promotion = actualPromotions.stream().filter(ap -> Objects.equals(ap.getIdOfBook(), p.getIdOfBook())).findFirst();
                promotion.ifPresent(ap -> p.setDiscountRate(ap.getDiscountRate() + p.getDiscountRate()));
            }
        );

I'm just exploring streams and I think my solution is clumpy. How would you solve this problem in more elegant fashion, with usage of streams and functional approach?

I'd first create a mapping from TimeDiscount::getIdOfBook to TimeDiscount:

Map<Long, TimeDiscount> accumulator = 
      actualPromotions.stream()
                     .collect(toMap(TimeDiscount::getIdOfBook, Function.identity()));

Then I'd do:

booksToReturn.forEach(e -> {
       TimeDiscount timeDiscount = accumulator.get(e.getIdOfBook());
       if (timeDiscount != null) e.setDiscountRate(e.getDiscountRate() + timeDiscount.getDiscountRate());
});

or if you want to stay with the use of Optional for some reason.

booksToReturn.forEach(e -> 
       Optional.ofNullable(accumulator.get(e.getIdOfBook()))
          .ifPresent(p -> e.setDiscountRate(e.getDiscountRate() + p.getDiscountRate()))
);

This improves upon the inefficient lookup in actualPromotions.stream() for each element of booksToReturn.

Java 8 Streams: Find Items From One List Based On Values From , Learn how to use data from one stream to find items in another. The idea here is to filter a list of Employee objects based on a list of  I'd like to replace all the items in the current list, with the same one's from new list. So after transformation, current list will be { Person(0, "X", 99), Person(1, "Y", 100) } Is it possible to do with Stream only.

One way you can do it is using:

booksToReturn.forEach(p -> actualPromotions.stream()
                .filter(actualPromotion -> actualPromotion.getIdOfBook().equals(p.getIdOfBook()))
                .forEach(actualPromotion -> p.setDiscountRate(p.getDiscountRate() + actualPromotion.getDiscountRate())));

Assuming actualPromotion.getIdOfBook() and p.getIdOfBook() would be unique across your Sets.

Update objects in one list based on values from second one using , List<​String> toSet()); // stream the list and use the set to filter it List<String> unavailable = list1.stream() .filter(e getStr().equals(e)) .count())<1) .collect(​Collectors. If you stream the first list and use a filter based on contains within the second. Java 8 stream distinct by multiple fields example. Learn to find distinct objects from a stream by comparing multiple fields or creating a custom key class.

I have not tested this: Try this one

  Map<Long,Integer> map1 = actualPromotions
   .stream() 
   .collect(Collectors.toMap(TimeDiscount::getIdOfBook,TimeDiscount::getDiscountRate));

then use this map in:

booksToReturn.stream()
   .filter(b->map1.containsKey(b.getIdOfBook()))
   .map(p->{p.setDiscountRate(map1.get(p.getIdOfBook()) + p.getDiscountRate());return p;}) // .map(p->setSumDiscountRate(map1.get(p.getIdOfBook()) + p.getDiscountRate()))
   .collect(Collectors.toList());

Try declare a new method in BookOverallData class.

public BookOverallData setSumDiscountRate(Integer dis){
  this.discountRate = dis;
  return this;
}

Beginning Java 8 Language Features: Lambda Expressions, Inner , When you work with streams, you will use these methods most of the time. to work with primitives; these interfaces contain methods to deal with primitive values. The code reads a list of integers and computes the sum of the squares of all odd The second time, the accumulator receives the value returned from its  In this tutorial, we will show you few Java 8 examples to demonstrate the use of Streams filter(), collect(), findAny() and orElse(). 1. Streams filter() and collect() 1.1 Before Java 8, filter a List like this :

Part 2: Processing Data with Java SE 8 Streams, As a refresher, the example in Listing 1 shows how to sum the values of only end up with a list of streams of streams (more precisely a Stream<Stream<String>​> ). of groupingBy() that takes another collector object as a second argument. Hi @Edaine,. To work with Lookup field, first you need to add the Parent List, here should be List 1 and List 2. Add a data connection in PowerApps. After that, take use of the Lookup function to find the proper field, for example, if here you would like to take use of the Price field of List 1, based on the Dropdown selection, then the formula should be:

10 Examples of Stream in Java 8, 1. How to use Streams in Java 8. You can use Streams to do a lot of things in Java 8. how to use Java 8 Stream API with simple * examples like filter objects, transforming a List with String more than 2 characters filtered = strList.stream() .​filter(x In second-line strList.stream() returns a Stream, and then we use the filter()  Stream.allMatch() method Stream.allMatch() method returns true if all the elements of the stream match the provided predicate condition.If even one of the elements does not match the predicate condition then the method skips the testing of the remaining elements using the concept of short-circuit evaluation Click to read in-depth article on Short-Circuits in Programming and returns false as

Java ArrayList - ArrayList methods, sorting, traversing, Java ArrayList tutorial shows how to work with ArrayList collection in Java. The example adds elements to an array list one by one. The get() method returns the second element, which is "orange". da.add(55); da.add(new Base()); da.​add(level); for (Object el : da) { System.out.println(el); } } }. In a nutshell, flatMap lets you replace each value of a stream with another stream, and then it concatenates all the generated streams into one single stream. Note that flatMap is a common pattern. You will see it again when dealing with Optional or CompletableFuture .

Comments
  • Nice, but I think it's better to avoid creating stream for each element as @Aomine done it.