该思考来源于日常工作中,特记此心得。
思考:如何快速将list中的每个item内部属性值改变并进行其他流体操作呢?
下面做个测试:如何先在list中统一改变某属性的值,然后再根据某个属性取出该属性值最小的对象
1:随便新建一个测试bean:
1 packagecom.dev.model;2
3 import javax.persistence.*;4
5 public classAopi {6 /**
7 * id8 */
9 @Id10 @GeneratedValue(strategy =GenerationType.IDENTITY)11 privateInteger id;12
13 /**
14 * 姓名15 */
16 privateString name;17
18 /**
19 * 年龄20 */
21 privateInteger age;22
23 /**
24 * 获取id25 *26 *@returnid - id27 */
28 publicInteger getId() {29 returnid;30 }31
32 /**
33 * 设置id34 *35 *@paramid id36 */
37 public voidsetId(Integer id) {38 this.id =id;39 }40
41 /**
42 * 获取姓名43 *44 *@returnname - 姓名45 */
46 publicString getName() {47 returnname;48 }49
50 /**
51 * 设置姓名52 *53 *@paramname 姓名54 */
55 public voidsetName(String name) {56 this.name =name;57 }58
59 /**
60 * 获取年龄61 *62 *@returnage - 年龄63 */
64 publicInteger getAge() {65 returnage;66 }67
68 /**
69 * 设置年龄70 *71 *@paramage 年龄72 */
73 public voidsetAge(Integer age) {74 this.age =age;75 }76
77 publicAopi(String name, Integer age) {78 this.name =name;79 this.age =age;80 }81
82 publicAopi() {83 }84
85 @Override86 publicString toString() {87 return "Aopi{" +
88 "id=" + id +
89 ", name='" + name + '\'' +
90 ", age=" + age +
91 '}';92 }93 }
View Code
2:新建一个单元测试:
@Testpublic voidtest01() {
List 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.
*
*
This is an intermediate
* operation.
*
*
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.
*
* @apiNoteThis method exists mainly to support debugging, where you want
* to see the elements as they flow past a certain point in a pipeline:
*
{@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());
* }
*
* non-interfering action to perform on the elements as
* they are consumed from the stream
*@returnthe new stream*/Stream peek(Consumer super T> action);