改思考来源于日常工作中,特记此心得。
思考:如何快速将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~^_^