參考資料
https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/
https://www.cnblogs.com/aoeiuv/p/5911692.html
http://www.java2s.com/Tutorials/Java/Java_Stream/index.htm
https://blog.csdn.net/qq_28410283/article/details/80633292
流的操作類型
流的操作類型分為兩種:
Intermediate
一個(gè)流可以后面跟隨零個(gè)或多個(gè) intermediate 操作。其目的主要是打開流,做出某種程度的數(shù)據(jù)映射/過濾,然后返回一個(gè)新的流,交給下一個(gè)操作使用。
這類操作都是惰性化的(lazy),就是說,僅僅調(diào)用到這類方法,并沒有真正開始流的遍歷。
map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered
Terminal
一個(gè)流只能有一個(gè) terminal 操作,當(dāng)這個(gè)操作執(zhí)行后,流就被使用“光”了,無法再被操作。所以這必定是流的最后一個(gè)操作。
Terminal 操作的執(zhí)行,才會(huì)真正開始流的遍歷,并且會(huì)生成一個(gè)結(jié)果,或者一個(gè) side effect。
forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator
還有一種操作被稱為short-circuiting。用以指:
- 對(duì)于一個(gè) intermediate 操作,如果它接受的是一個(gè)無限大(infinite/unbounded)的 Stream,但返回一個(gè)有限的新 Stream。
- 對(duì)于一個(gè) terminal 操作,如果它接受的是一個(gè)無限大的 Stream,但能在有限的時(shí)間計(jì)算出結(jié)果。
當(dāng)操作一個(gè)無限大的 Stream,而又希望在有限時(shí)間內(nèi)完成操作,則在管道內(nèi)擁有一個(gè) short-circuiting 操作是必要非充分條件。
anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit
流只有在進(jìn)行Terminal或者個(gè)別Short-circuiting之后才會(huì)開始執(zhí)行
流無法復(fù)用,用完即銷毀
流的分類
特殊流
專門用于處理基本類型,int,double,long
IntStream,DoubleStream,LongStream
對(duì)象流
處理對(duì)象類型
流常用方法
import org.junit.Test;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import lombok.Data;
import lombok.experimental.Accessors;
public class StreamTest {
/** 生成連續(xù)數(shù)字,含頭不含尾*/
@Test
public void testRange() {
IntStream.range(0, 10).forEach(System.out::println);
}
/** 生成連續(xù)數(shù)字,含頭含尾*/
@Test
public void testRangeClosed() {
IntStream.rangeClosed(0, 10).forEach(System.out::println);
}
/** 生成從0開始遞增3的前10位數(shù)字*/
@Test
public void testIterate() {
IntStream.iterate(0, e -> e + 3).limit(10).forEach(System.out::println);
}
/** 生成從0開始遞增3,跳過前10位后的前5位數(shù)字*/
@Test
public void testSkip() {
IntStream.iterate(0, e -> e + 3).skip(10).limit(5).forEach(System.out::println);
}
/** 生成當(dāng)前日期開始,遞增1天的前5位時(shí)間*/
@Test
public void testDateIterate() {
Stream.iterate(LocalDate.now(), e -> e.plusDays(1)).limit(5).forEach(System.out::println);
}
/** 基本類型轉(zhuǎn)包裝類型*/
@Test
public void testBoxed() {
List<Integer> collect = IntStream.range(10, 20).boxed().collect(Collectors.toList());
System.out.println(collect);
}
/** 基本類型裝對(duì)象類型*/
@Test
public void testMapToObj() {
List<TestPo> collect =
IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e)).collect(Collectors.toList());
System.out.println(collect);
}
/** 統(tǒng)計(jì)*/
@Test
public void testCount() {
long count = IntStream.range(0, 10).count();
System.out.println(count);
}
/** 去重*/
@Test
public void testDistinct() {
IntStream.range(0, 10).map(e -> e % 2).forEach(System.out::println);
IntStream.range(0, 10).map(e -> e % 2).mapToObj(e->new TestPo().setOrder(e)).distinct().forEach(System.out::println);
}
/** 求和*/
@Test
public void testSum() {
int sum = IntStream.range(0, 10).sum();
System.out.println(sum);
}
/** 過濾,保留filter中返回值為true的屬性*/
@Test
public void testFilter() {
IntStream.range(0, 10).filter(e -> e >= 5).forEach(System.out::println);
}
/** 聚合操作*/
@Test
public void testReduce() {
BigDecimal reduce =
DoubleStream.iterate(1, e->e+1).limit(10).mapToObj(BigDecimal::valueOf).reduce(BigDecimal.ZERO,
BigDecimal::add);
System.out.println(reduce.toPlainString());
}
/** 把input Stream 中的層級(jí)結(jié)構(gòu)扁平化,就是將最底層元素抽出來放到一起,返回對(duì)象必須是Stream*/
@Test
public void testFlatMap() {
List<Integer> collect = IntStream.rangeClosed(0, 10).boxed().collect(Collectors.toList());
List<Integer> collect1 = IntStream.rangeClosed(5, 15).boxed().collect(Collectors.toList());
List<Integer> collect2 = IntStream.rangeClosed(10, 20).boxed().collect(Collectors.toList());
List<List<Integer>> list = new ArrayList<>();
list.add(collect);
list.add(collect1);
list.add(collect2);
System.out.println(list);
List<Integer> collect3 = list.stream().flatMap(e -> e.stream()).collect(Collectors.toList());
System.out.println(collect3);
}
/** 對(duì)每個(gè)元素執(zhí)行操作并返回一個(gè)新的 Stream*/
@Test
public void testPeek() {
List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e).setName("test" + e))
.collect(Collectors.toList());
System.out.println(collect);
List<TestPo> collect1 = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e).setName("test" + e))
.peek(e -> e.setOrder(e.getOrder() + 10)).collect(Collectors.toList());
System.err.println(collect1);
}
/** 聚合為map*/
@Test
public void testToMap() {
List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e).setName("test" + e))
.collect(Collectors.toList());
Map<String, TestPo> collect1 = collect.stream().collect(Collectors.toMap(e -> e.getName(), e -> e));
System.out.println(collect1);
}
/** 按指定屬性分組*/
@Test
public void testGroupingBy() {
List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e % 3).setName("test" + e))
.collect(Collectors.toList());
Map<Integer, List<TestPo>> collect1 = collect.stream().collect(Collectors.groupingBy(e -> e.getOrder()));
System.out.println(collect1);
}
/** 按指定屬性分組后,對(duì)每組元素進(jìn)行操作*/
@Test
public void testGroupingByExpand() {
List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e % 3).setName("test" + e))
.collect(Collectors.toList());
Map<Integer, Set<String>> collect1 = collect.stream().collect(
Collectors.groupingBy(e -> e.getOrder(), Collectors.mapping(e -> e.getName(), Collectors.toSet())));
System.out.println(collect1);
}
/** 按指定屬性分組后,對(duì)每組元素進(jìn)行操作*/
@Test
public void testGroupingByExpand1() {
List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e % 3).setName("test" + e))
.collect(Collectors.toList());
Map<Integer, Long> collect1 =
collect.stream().collect(Collectors.groupingBy(e -> e.getOrder(), Collectors.counting()));
System.out.println(collect1);
}
/** 根據(jù)判斷條件對(duì)數(shù)據(jù)進(jìn)行分割,滿足條件的key為true*/
@Test
public void testPartitioningBy() {
List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e % 3).setName("test" + e))
.collect(Collectors.toList());
Map<Boolean, List<TestPo>> collect1 =
collect.stream().collect(Collectors.partitioningBy(e -> e.getOrder() > 1));
System.out.println(collect1);
}
/** 排序操作*/
@Test
public void testSort() {
List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e % 3).setName("test" + e))
.collect(Collectors.toList());
System.out.println(collect);
collect.sort(Comparator.comparing(e -> e.getOrder()));
System.out.println(collect);
}
/** 排序操作,可以多字段排序,可指定排序器,可控制null值處理及正序倒敘*/
@Test
public void testSorted() {
List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e % 3).setName("test" + e))
.sorted(Comparator.comparingInt(e -> e.getOrder())).collect(Collectors.toList());
System.out.println(collect);
}
/** 并行流(fork join)*/
@Test
public void testParallel() {
IntStream.range(0, 10).parallel().boxed().forEach(System.out::println);
}
/** 并行流(fork join)*/
@Test
public void testParallel1() {
List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e).setName("test" + e))
.collect(Collectors.toList());
collect.parallelStream().map(e -> e.getOrder()).forEach(System.out::println);
collect.parallelStream().map(e -> e.getOrder()).forEachOrdered(System.err::println);
}
/** 全部不匹配*/
@Test
public void testNoneMatch() {
List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e).setName("test" + e))
.collect(Collectors.toList());
System.out.println(collect.stream().noneMatch(e -> e.getOrder() > 8));
}
/** 任意一個(gè)匹配*/
@Test
public void testAnyMatch() {
List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e).setName("test" + e))
.collect(Collectors.toList());
System.out.println(collect.stream().anyMatch(e -> e.getOrder() > 8));
}
/** 全部匹配*/
@Test
public void testAllMatch() {
List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e).setName("test" + e))
.collect(Collectors.toList());
System.out.println(collect.stream().allMatch(e -> e.getOrder() > 8));
}
@Data
@Accessors(chain = true)
public static class TestPo {
private Integer order;
private String name;
private TestPo1 po1;
@Data
public static class TestPo1{
private String age;
}
}
}