Stream基本概念
流是數據渠道,用於操作數據源,所生成一種新的元素序列。集合講的是數據,流講的是計算,是操作。使用Stream API 對集合的數據進行操作,類似於SQL執行的數據庫查詢,也可以用來並行執行操作,其提供了一種高效且易於使用的處理數據方式。
- Stream不會改變數據源對象,相反會返回產生一個持有結果的新Stream。
- Steam操作是延遲執行的,這意味着他們會等到需要結果的時候才執行。
- 一個流只能使用一次,使用後就會被關閉。
創建Stream
方法一
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();
方法二
Stu[] stus = new Stu[10];
Stream<Stu> stream2 = Arrays.stream(stus);
方法三
Stream<String> stream3 = Stream.of("hxh", "aj", "hhh");
Stream中間操作
Stream是一箇中間操作,如果沒有被使用的話,將不會執行。
可以進行一系列的Stream操作,在需要結果時統一執行。
代碼示例:
- 以下通用實體,創建一個Animal的list
@Data
public class Animal {
String name;
String type;
Integer age;
public Animal(){}
public Animal(String name,String type,Integer age){
this.name = name;
this.type = type;
this.age = age;
}
public static List<Animal> getAnimals(){
List<Animal> animals = new ArrayList<>();
animals.add(new Animal("田園犬","犬科",5));
animals.add(new Animal("獵犬","犬科",15));
animals.add(new Animal("哈士奇","犬科",6));
animals.add(new Animal("咖啡貓","貓科",33));
animals.add(new Animal("小貓","貓科",4));
animals.add(new Animal("大貓","貓科",18));
return animals;
}
}
- 驗證延遲加載(中間操作)
public static void main(String[] args) {
//創建一個list
List<Animal> animals = Animal.getAnimals();
//選擇年齡大於10的動物(中間操作)
Stream<Animal> s = animals.stream().filter(animal -> {
System.out.println("驗證延遲加載");
return animal.getAge()>10;
});
//將上一步生成的流再次篩選年齡大於20的動物(中間操作)
//斷點到此處,控制檯無打印
Stream<Animal> s1 = s.filter(animal -> animal.getAge()>20);
//斷點到此處,控制打印
//終止操作執行後,所有的中間操作一次執行,此時就稱爲延遲加載或者惰性求值
List<Animal> l = s1.collect(Collectors.toList());
l.forEach(e-> System.out.println(e));
}
篩選
filter(過濾器)
功能:根據條件過濾列表數據
代碼:
List<Animal> animals = Animal.getAnimals();
List<Animal> list = animals.stream().filter(animal -> animal.getAge() > 10).collect(Collectors.toList());
list.forEach(l-> System.out.println(l.getName()+":"+l.getAge()));
輸出結果:
獵犬:15
咖啡貓:33
大貓:18
limit(限定元素數量)
功能:通過截斷流,使流中元素個數不超過指定數量
代碼:
List<Animal> animals = Animal.getAnimals();
List<Animal> list = animals.stream().filter(animal -> animal.getAge() > 10).limit(1).collect(Collectors.toList());
list.forEach(l-> System.out.println(l.getName()+":"+l.getAge()));
輸出結果:
獵犬:15
skip(跳過元素)
功能:返回一個跳過前n個元素的流,若流中元素不足n個,則返回一個空流
代碼:
List<Animal> animals = Animal.getAnimals();
List<Animal> list = animals.stream().filter(animal -> animal.getAge() > 10).skip(1).collect(Collectors.toList());
list.forEach(l-> System.out.println(l.getName()+":"+l.getAge()));
輸出結果:
咖啡貓:33
大貓:18
distinct(去重)
功能:通過截斷流,使流中元素個數不超過指定數量
代碼:
List<Animal> animals = Animal.getAnimals();
//在列表中插入同樣的一個田園犬
animals.add(new Animal("田園犬","犬科",5));
//先篩選出田園犬的列表
animals = animals.stream().filter(animal -> animal.getName().equals("田園犬")).collect(Collectors.toList());
//循環輸出
animals.forEach(l-> System.out.println(l.getName()+":"+l.getAge()));
System.out.println("-------------");
//去重操作
List<Animal> list = animals.stream().distinct().collect(Collectors.toList());
list.forEach(l-> System.out.println(l.getName()+":"+l.getAge()));
輸出結果:
田園犬:5
田園犬:5
-------------
田園犬:5