Change thinking comes from daily work, so remember this experience.
Thinking: how to quickly change the internal attribute value of each item in the list and perform other fluid operations?
Here's a test: how to get the object in the list according to the minimum value of a property
1: create any new test bean:
1 package com.dev.model; 2 3 import javax.persistence.*; 4 5 public class Aopi { 6 /** 7 * id 8 */ 9 @Id 10 @GeneratedValue(strategy = GenerationType.IDENTITY) 11 private Integer id; 12 13 /** 14 * Full name 15 */ 16 private String name; 17 18 /** 19 * Age 20 */ 21 private Integer age; 22 23 /** 24 * Get id 25 * 26 * @return id - id 27 */ 28 public Integer getId() { 29 return id; 30 } 31 32 /** 33 * Set id 34 * 35 * @param id id 36 */ 37 public void setId(Integer id) { 38 this.id = id; 39 } 40 41 /** 42 * Get name 43 * 44 * @return name - Full name 45 */ 46 public String getName() { 47 return name; 48 } 49 50 /** 51 * Set name 52 * 53 * @param name Full name 54 */ 55 public void setName(String name) { 56 this.name = name; 57 } 58 59 /** 60 * Age of acquisition 61 * 62 * @return age - Age 63 */ 64 public Integer getAge() { 65 return age; 66 } 67 68 /** 69 * Age setting 70 * 71 * @param age Age 72 */ 73 public void setAge(Integer age) { 74 this.age = age; 75 } 76 77 public Aopi(String name, Integer age) { 78 this.name = name; 79 this.age = age; 80 } 81 82 public Aopi() { 83 } 84 85 @Override 86 public String toString() { 87 return "Aopi{" + 88 "id=" + id + 89 ", name='" + name + '\'' + 90 ", age=" + age + 91 '}'; 92 } 93 }
2: create a new unit test:
@Test public void test01() { List<Aopi> aopiList = Lists.newArrayList(); Aopi aopi = new Aopi("1", 1); Aopi aop2 = new Aopi("2", 2); Aopi aop3 = new Aopi("3", 3); Aopi aop4 = new Aopi("4", 4); aopiList.addAll(Arrays.asList(aopi, aop2, aop3, aop4)); //The first way aopiList.forEach(item -> item.setName(item.getName() + "_test")); System.out.println( aopiList.stream().min((o1, o2) -> { if (Objects.equals(o1.getAge(), o2.getAge())) return 0; return o1.getAge() > o2.getAge() ? 1 : -1; }).get().toString() ); System.out.println("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"); //The second way System.out.println( aopiList.stream().peek(item -> item.setName(item.getName() + "_test")).min((o1, o2) -> { if (Objects.equals(o1.getAge(), o2.getAge())) return 0; return o1.getAge() > o2.getAge() ? 1 : -1; }).get().toString() ); }
Note 1: test the first way to comment out the second way, and vice versa
notice2: list.stream().foreach -> list.foreach()
3. See the test results:
The first test result:
The second test result:
Conclusion:
(1): using stream.foreach, you can also change the internal property value of each item in the list, etc., but you need to perform "secondary flow processing" to get the smallest item in the list (filter according to age).
(2): stream.peek can get the smallest item directly compared with stream.foreach().
Reason:
(1): the operation of stream.foreach is void. In addition to changing the property value, other operations can also be performed. So we need to do "secondary flow processing".
default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }
(1): the operation of stream.peek returns a new stream, and the original intention of the design is to debug, so using stream. Peek() must process the stream once and then generate a new stream.
/** * Returns a stream consisting of the elements of this stream, additionally * performing the provided action on each element as elements are consumed * from the resulting stream. * * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>. * * <p>For parallel stream pipelines, the action may be called at * whatever time and in whatever thread the element is made available by the * upstream operation. If the action modifies shared state, * it is responsible for providing the required synchronization. * * @apiNote This method exists mainly to support debugging, where you want * to see the elements as they flow past a certain point in a pipeline: * <pre>{@code * Stream.of("one", "two", "three", "four") * .filter(e -> e.length() > 3) * .peek(e -> System.out.println("Filtered value: " + e)) * .map(String::toUpperCase) * .peek(e -> System.out.println("Mapped value: " + e)) * .collect(Collectors.toList()); * }</pre> * * @param action a <a href="package-summary.html#NonInterference"> * non-interfering</a> action to perform on the elements as * they are consumed from the stream * @return the new stream */ Stream<T> peek(Consumer<? super T> action);
bye~^_^