java8爲我們提供了一種Stream操作,讓我們對集合或者數組的操作更加簡單。
什麼是流式操作?
提示:如果你瞭解什麼是流式操作,那你可以跳過以下部分內容!!!
舉一個簡單的例子。
下面是一個普通的Person類,有name,age,scole 三個屬性,以及對應的get,set方法。
public class Person{
private String name;
private Integer age;
private Integer scole;
public Person(String name, Integer age, Integer scole){
this.name=name;
this.age=age;
this.scole=scole;
}
public String getName() {
return name;
}
public Person(){
}
public Person setName(String name) {
this.name = name;
return this;
}
public Integer getAge() {
return age;
}
public Person setAge(Integer age) {
this.age = age;
return this;
}
public Integer getScole() {
return scole;
}
public Person setScole(Integer scole) {
this.scole = scole;
return this;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", scole=" + scole +
'}';
}
}
我們實例化person累的時候,可以有以下兩種方式:
- 通過類的有參構造函數。
Person per=new Person("zhansan",10,100);
- 通過類的無參構造函數實例化該類,調用屬性的set方法對屬性進行賦值。
Person per =new Person();
per.setName="zhangsan";
per.setAge=10;
per.setScole=100;
我們知道屬性的set方法是沒有返回值。
public void setName(String name){
this.name=name;
}
我們對屬性的set方法進行改造:
public Person setName(String name){
this.name=name;
return this;
}
改造之後的set方法會返回一個Person對象,所以我們就可以這樣對屬性進行賦值:
Person per =new Person();
per.setName("zhangsan").setAge(10).setScole(100);
這就是簡單的流式操作。
集合的流式操作
流式操作的特點
- 不是一個數據結構,不負責任何的順序存儲。
- 更像是一個迭代器,有序的獲取到數據源中的每一個數據,並且可以對這些數據進行一些操作。
- 流式操作的每一個方法返回值都是流本身。
流式操作的一般步驟
- 獲取數據源:集合,數組。
- 對數據進行處理裏的過程(中間操作):過濾,排序,映射等
- 對流中的數據的整合(最終操作):轉成集合等
獲取流Stream
創建一個數據源
public class Data {
public static ArrayList getData(){
ArrayList<Person> list=new ArrayList<>();
list.add(new Person("xiaoming ",10,100));
list.add(new Person("xiahong ",9,99));
list.add(new Person("xiaowang ",8,98));
list.add(new Person("xiaodong ",7,97));
list.add(new Person("xiaocao ",6,96));
list.add(new Person("xiaocui ",5,95));
list.add(new Person("xiaoliang ",4,94));
return list;
}
}
獲取數據源
//獲取數據源
Stream<Person> s= Data.getData().stream();
最終操作
collector操作
//將stream結果轉成list
List<Person> list = s.collect(Collectors.toList());
//將stream結果轉化爲set
Set<Person> set=s.collect(Collectors.toSet());
//將stream操作結果轉成map
//該map以name爲key,成績scole爲value
Map<String Integer> map=s.collect(Collectors.toMap(ele->ele.getName(),ele->ele.getScole()));
結果:
//轉成list結果
[Person{name='xiaoming ', age=10, scole=100}, Person{name='xiahong ', age=9, scole=99}, Person{name='xiaowang ', age=8, scole=98}, Person{name='xiaodong ', age=7, scole=97}, Person{name='xiaocao ', age=6, scole=96}, Person{name='xiaocui ', age=5, scole=95}, Person{name='xiaoliang ', age=4, scole=94}, Person{name='xiaoming ', age=10, scole=100}]
//轉成set結果
[Person{name='xiaoming ', age=10, scole=100}, Person{name='xiaocui ', age=5, scole=95}, Person{name='xiaoliang ', age=4, scole=94}, Person{name='xiahong ', age=9, scole=99}, Person{name='xiaocao ', age=6, scole=96}, Person{name='xiaowang ', age=8, scole=98}, Person{name='xiaodong ', age=7, scole=97}]
//轉成map結果
Person{name='xiaoliang ', age=4, scole=94}
Person{name='xiaocui ', age=5, scole=95}
Person{name='xiaocao ', age=6, scole=96}
Person{name='xiaodong ', age=7, scole=97}
Person{name='xiaowang ', age=8, scole=98}
Person{name='xiahong ', age=9, scole=99}
Person{name='xiaoming ', age=10, scole=100}
reduce操作
根據指定的計算模型將Stream中的值計算得到一個最終結果
//一個簡單的例子
//計算流中數據的和
Stream<Integer> s1=Stream.of(1,2,3,4,5,6,7,8,9,10);
Optional<Integer> ret= s1.reduce((n1, n2)-> n1+n2);
System.out.println(ret.get());
很顯然,結果爲55。那麼是如何計算的呢?
max和min操作
max操作,找出流中元素最大的一個,min找出流中元素最小的一個
找出分數最大的一個元素,找出年齡最小的一個元素
//max操作
Person max = s.max((ele1, ele2) -> ele1.getScole() - ele2.getScole()).get();
System.out.println(max);
//min操作
Person min = s.min((ele1, ele2) -> ele1.getAge() - ele2.getAge()).get();
System.out.println(min);
結果
//分數最高的元素爲
Person{name='xiaoming ', age=10, scole=100}
//年齡最小的元素爲
Person{name='xiaoliang ', age=4, scole=94}
antMatch,allMatch,noneMatch操作
anyMatch:對於指定條件,集合中只要有即返回true
allMatch:對於指定條件,集合中是不是全滿足,如果全滿足即返回true,有一個不滿就返回false
noneMatch:對於指定條件,集合中是不是全都不滿足,如果全都不滿足即返回true,有任何一個滿足就返回false
//判斷集合中是否包含成績大於60的元素
boolean b = s.anyMatch(ele -> ele.getScole() >60);
System.out.println(b);
//返回結果爲true
-------------------------------
//判斷集合中元素的成績是否都大於95
boolean b1 = s.allMatch(ele -> ele.getScole() > 95);
System.out.println(b1);
//很顯然,返回結果爲false
--------------------------------
//判斷集合中所有學員成績是不是沒有低於60分的
boolean b3 = s.noneMatch(ele -> ele.getScole() < 60);
System.out.println(b3);
//返回結果爲true
count操作
count操作可以對Stream流中的元素個數進行計數
//count操作
System.out.println(s.count());
//結果爲 7
foreach操作
這個不用講大家也知道,就是類似於遍歷,讓流中的每個元素都執行一次你設定的操作。
//foreach操作,打印出每個元素,讓每個元素打印自己
s.forEach(System.out::println);
//結果
Person{name='xiaoming ', age=10, scole=100}
Person{name='xiahong ', age=9, scole=99}
Person{name='xiaowang ', age=8, scole=98}
Person{name='xiaodong ', age=7, scole=97}
Person{name='xiaocao ', age=6, scole=96}
Person{name='xiaocui ', age=5, scole=95}
Person{name='xiaoliang ', age=4, scole=94}