是數(shù)據(jù)渠道,用于操作集合、數(shù)組等生成的元素序列。
Stream操作的三個(gè)步驟:
創(chuàng)建Stream
中間操作
終止操作
一、獲取stream的四種方式
通過(guò)collection系列集合的stream()或parallelStream()獲取。
@Test
void test11(){
? ? List<String> list = new ArrayList<>();
? ? Stream<String> stringStream = list.stream();
}
通過(guò)Arrays中的靜態(tài)方法stream()獲取數(shù)組流。
@Test
void test11(){
? ? Person[] person = new Person[10];
? ? Arrays.stream(person);
}
通過(guò)Stream中的靜態(tài)方法of()。
@Test
void test11(){
? ? Stream<String> stream = Stream.of("a", "b", "c");
}
創(chuàng)建無(wú)限流
/**
* 迭代
*/
@Test
void test11(){
? ? Stream<Integer> integerStream = Stream.iterate(0, x -> x + 2);
}
/**
* 生成
*/
@Test
void test11(){
? ? Stream.generate(() -> Math.random());
}
二、中間操作
中間操作不會(huì)執(zhí)行任何操作,只有終止操作才會(huì)一次性輸出全部值,即“惰性求值”。
2.1 篩選與切片
filter——接收l(shuí)amdba,從流中排除某些元素
@Test
void test12(){
? ? List<Person> personList = Arrays.asList(
? ? ? ? new Person("Java旅途",18),
? ? ? ? new Person("Java旅途",20)
? ? );
? ? // 中間操作
? ? Stream<Person> personStream = personList.stream()
? ? ? ? .filter(e -> e.getAge() > 18);
? ? // 終止操作
? ? personStream.forEach(System.out::println);
}
limit——截?cái)嗔?,使其元素不超過(guò)給定數(shù)量
@Test
void test12(){
? ? List<Person> personList = Arrays.asList(
? ? ? ? new Person("Java旅途",18),
? ? ? ? new Person("Java旅途",20)
? ? );
? ? personList.stream()
? ? ? ? .limit(1)
? ? ? ? .forEach(System.out::println);
}
skip(n)——跳過(guò)元素,返回一個(gè)扔掉前n個(gè)元素的流,若不足n個(gè),則返回一個(gè)空流。與limit(n)互補(bǔ)。
@Test
void test12(){
? ? List<Person> personList = Arrays.asList(
? ? ? ? new Person("Java旅途",18),
? ? ? ? new Person("Java旅途",20)
? ? );
? ? personList.stream()
? ? ? ? .skip(1)
? ? ? ? .forEach(System.out::println);
}
distinct——篩選,通過(guò)生成元素的hashCode()和equals(),去除重復(fù)元素。
@Test
void test12(){
? ? List<Person> personList = Arrays.asList(
? ? ? ? new Person("Java旅途",18),
? ? ? ? new Person("Java旅途",20),
? ? ? ? new Person("Java旅途",20)
? ? );
? ? personList.stream()
? ? ? ? .distinct()
? ? ? ? .forEach(System.out::println);
}
注意:使用distinct的時(shí)候需要重寫實(shí)體的hashCode()和equals()方法。
2.2 映射
map——接收l(shuí)amdba,將元素轉(zhuǎn)換成其他形式或提取信息。接收一個(gè)函數(shù)作為參數(shù),該函數(shù)會(huì)被應(yīng)用到每個(gè)元素上,并將其映射成一個(gè)新的元素。
/**
* 獲取personList的所有name
*/
@Test
void test13(){
? ? List<Person> personList = Arrays.asList(
? ? ? ? new Person("Java旅途",18),
? ? ? ? new Person("Java旅途",20),
? ? ? ? new Person("Java旅途",20)
? ? );
? ? personList.stream()
? ? ? ? .map(Person::getName)
? ? ? ? .forEach(System.out::println);
}
flatMap——接收一個(gè)函數(shù)作為參數(shù),將流中的每個(gè)值都換成另一個(gè)流,然后把所有流生成一個(gè)流。
// 將字符串轉(zhuǎn)換為字符,并將字符放進(jìn)list返回
static Stream<Character> filterCharcter(String string){
? ? List<Character> list = new ArrayList<>();
? ? for (Character ch : string.toCharArray()){
? ? ? ? list.add(ch);
? ? }
? ? return list.stream();
}
@Test
void test13(){
? ? List<String> list = Arrays.asList("aaa","bbb","ccc");
? ? list.stream()
? ? ? ? .flatMap(LamdbaApplicationTests::filterCharcter)
? ? ? ? .forEach(System.out::println);
}
2.3 排序
sorted()——自然排序(comparable)
sorted(comparator com)——定制排序(comparator )
/**
* 定制排序,e1和e2按age排序,age一樣按name排
*/
@Test
void test14(){
? ? List<Person> personList = Arrays.asList(
? ? ? ? ? ? new Person("Java旅途",18),
? ? ? ? ? ? new Person("Java旅途",20)
? ? );
? ? personList.stream()
? ? ? ? .sorted((e1,e2) -> {
? ? ? ? ? ? if(e1.getAge() == e2.getAge()){
? ? ? ? ? ? ? ? return e1.getName().compareTo(e2.getName());
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? return e1.getAge()+"".compareTo(e2.getAge()+"");
? ? ? ? ? ? }
? ? ? ? }).forEach(System.out::println);
}
三、終止操作
3.1 查找與匹配
完善一下Person類
@Data
public class Person implements Serializable {
? ? private static final long serialVersionUID = -7008474395345458049L;
? ? private String name;
? ? private int age;
? ? private Status status;
? ? public Person() {
? ? }
? ? public Person(String name, int age) {
? ? ? ? this.name = name;
? ? ? ? this.age = age;
? ? }
? ? public Person(String name, int age, Status status) {
? ? ? ? this.name = name;
? ? ? ? this.age = age;
? ? ? ? this.status = status;
? ? }
? ? public enum Status {
? ? ? ? FRER,
? ? ? ? BUSY;
? ? }
}
allMatch——檢查是否匹配所有元素
/**
* 是否所有元素都是Fire狀態(tài),是返回true
*/
@Test
void test15(){
? ? List<Person> personList1 = Arrays.asList(
? ? ? ? new Person("Java旅途",18, Person.Status.FRER),
? ? ? ? new Person("Java旅途",20, Person.Status.BUSY)
? ? );
? ? boolean b = personList1.stream()
? ? ? ? .allMatch(e -> e.getStatus().equals(Person.Status.FRER));
? ? System.out.println(b);
}
anyMatch——檢查是否至少匹配一個(gè)元素
@Test
void test15(){
? ? List<Person> personList1 = Arrays.asList(
? ? ? ? new Person("Java旅途",18, Person.Status.FRER),
? ? ? ? new Person("Java旅途",20, Person.Status.BUSY)
? ? );
? ? boolean b = personList1.stream()
? ? ? ? .anyMatch(e -> e.getStatus().equals(Person.Status.FRER));
? ? System.out.println(b);
}
noneMatch——檢查是否所有元素都不匹配
@Test
void test15(){
? ? List<Person> personList1 = Arrays.asList(
? ? ? ? new Person("Java旅途",18, Person.Status.FRER),
? ? ? ? new Person("Java旅途",20, Person.Status.BUSY)
? ? );
? ? boolean b = personList1.stream()
? ? ? ? .noneMatch(e -> e.getStatus().equals(Person.Status.FRER));
? ? System.out.println(b);
}
findFirst——返回第一個(gè)元素
@Test
void test15(){
? ? List<Person> personList1 = Arrays.asList(
? ? ? ? new Person("Java旅途",18, Person.Status.FRER),
? ? ? ? new Person("Java旅途",20, Person.Status.BUSY)
? ? );
? ? Optional b = personList1.stream()
? ? ? ? .findFirst();
? ? System.out.println(b.get());
}
findAny——返回當(dāng)前流中的任意元素
@Test
void test15(){
? ? List<Person> personList1 = Arrays.asList(
? ? ? ? new Person("Java旅途",18, Person.Status.FRER),
? ? ? ? new Person("Java旅途",20, Person.Status.BUSY)
? ? );
? ? Optional b = personList1.stream()
? ? ? ? .findAny();
? ? System.out.println(b.get());
}
count——返回流中元素的總數(shù)
max——返回流中最大值
min——返回流中最小值
3.2 規(guī)約
reduce(T identity, BinaryOperator)/reduce(BinaryOperator)——可以將流中元素反復(fù)結(jié)合起來(lái),得到一個(gè)值。
/**
? * reduce 第一個(gè)參數(shù)是起始值
? */
@Test
void test16(){
? ? List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
? ? Integer sum = list.stream()
? ? ? ? ? .reduce(0,(x,y) -> x+y);
? ? System.out.println(sum);
? ? Optional<Integer> reduce = list.stream()
? ? ? ? ? ? ? ? ? .reduce((x, y) -> x + y);
? ? System.out.println(reduce.get());
}
3.3 收集
collect——將流轉(zhuǎn)化為其他形式。接收一個(gè)Collector接口的實(shí)現(xiàn)。用于給Stream中元素做匯總的方法。
/**
* 取出名字放在一個(gè)list中
*/
@Test
void test16(){
? ? List<Person> personList1 = Arrays.asList(
? ? ? ? new Person("Java旅途",18, Person.Status.FRER),
? ? ? ? new Person("Java旅途",20, Person.Status.BUSY)
? ? );
? ? List<String> collect = personList1.stream()
? ? ? ? .map(Person::getName)
? ? ? ? .collect(Collectors.toList());
? ? collect.forEach(System.out::println);
}
亞馬遜測(cè)評(píng) www.yisuping.com