改思考來源於日常工作中,特記此心得。
思考:如何快速將list中的每個item內部屬性值改變並進行其他流體操作呢?
下面做個測試:如何先在list中統一改變某屬性的值,然后再根據某個屬性取出該屬性值最小的對象
1:隨便新建一個測試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 * 姓名 15 */ 16 private String name; 17 18 /** 19 * 年齡 20 */ 21 private Integer age; 22 23 /** 24 * 獲取id 25 * 26 * @return id - id 27 */ 28 public Integer getId() { 29 return id; 30 } 31 32 /** 33 * 設置id 34 * 35 * @param id id 36 */ 37 public void setId(Integer id) { 38 this.id = id; 39 } 40 41 /** 42 * 獲取姓名 43 * 44 * @return name - 姓名 45 */ 46 public String getName() { 47 return name; 48 } 49 50 /** 51 * 設置姓名 52 * 53 * @param name 姓名 54 */ 55 public void setName(String name) { 56 this.name = name; 57 } 58 59 /** 60 * 獲取年齡 61 * 62 * @return age - 年齡 63 */ 64 public Integer getAge() { 65 return age; 66 } 67 68 /** 69 * 設置年齡 70 * 71 * @param 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:新建一個單元測試:
@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)); //第一種方式 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"); //第二種方式 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() ); }
notice1:測試第一種方式注釋掉第二種,反之亦如此
notice2:list.stream().foreach -> list.foreach()
3:看測試結果:
第一種測試結果:
第二種測試結果:
結論:
(1):使用stream.foreach也可以更改list中的每個item的內部屬性值等等,但是要進行“二次流處理”,才能得到list中最小的item(根據age篩選)
(2):stream.peek比stream.foreach()可以跟直接拿到最小的item(根據age篩選)
原因:
(1):stream.foreach的操作是void的,除了更改屬性值還可以進行其他操作等。因此要做“二次流處理”。
default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }
(1):stream.peek的操作是返回一個新的stream的,且設計的初衷是用來debug調試的,因此使用steam.peek()必須對流進行一次處理再產生一個新的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~^_^