java8添加了一個抽象流Stream,可讓咱們像寫sql同樣操做集合元素。Stream將要處理的元素看作是一種流, 在管道中傳輸,並進行處理,最後由終止操做獲得處理的結果。java
Stream是一個來自特定元素隊列並支持聚合操做sql
stream():即單線程的方式去操做流多線程
parallelStream():即多線程方式去操做流dom
@Test public void test() { //1經過Collection提供的stream()和parallelStream()方法 List<String> list = Arrays.asList("a","b","c"); Stream<String> stream1 = list.stream(); Stream<String> stream2 = list.parallelStream(); //2經過Arrays的靜態方法stream() String[] strs= {"a","b","c"}; Stream<String> stream3 = Arrays.stream(strs); //3經過Stream類中的靜態方法of() Stream<String> stream4 = Stream.of("a","b","c"); //4經過Stream類的iterate方法生成無限流 Stream<Integer> stream5 = Stream.iterate(0, (x)->x+1); //5經過Stream的generate方法生成無限流 Stream.generate(()->Math.random()); }
使用 filter(Predicate<? super T> predicate)來按照必定規則對流中元素進行過濾ide
@Test public void test() { List<Integer> list = Arrays.asList(1,2,3,4,5); Stream<Integer> stream = list.stream(); stream = stream.filter((x)->x.compareTo(2)>0); stream.forEach(System.out::println); } 輸出: 3 4 5 @Test public void test2() { List<Integer> list = Arrays.asList(1,2,3,4,5); Stream<Integer> stream = list.stream(); stream = stream.filter( (x)->{ System.out.println(x); return x.compareTo(2)>0;} ); } 結果:沒有任何輸出,這也就是前面說的Stream操做是延遲執行的,只有當終止操做這些中間操做纔會依次執行
使元素的個數不超過指定的數目函數
@Test public void test() { List<Integer> list = Arrays.asList(1,2,3,4,5); Stream<Integer> stream = list.stream(); stream=stream.limit(3); stream.forEach(System.out::println); } 輸出: 1 2 3 能夠看到只輸出了給定個元素
跳過流中前幾個元素this
@Test public void test4() { List<Integer> list = Arrays.asList(1,2,3,4,5); Stream<Integer> stream = list.stream(); stream=stream.skip(2); stream.forEach(System.out::println); } 輸出: 3 4 5 跳過了前兩個元素
兩個元素經過hashCode()判斷兩個元素是否相同線程
@Test public void test5() { List<Integer> list = Arrays.asList(1,2,3,4,5,5); Stream<Integer> stream = list.stream(); stream.distinct().forEach(System.out::println); } 輸出: 1 2 3 4 5
map(method)接受一個方法,把流中的元素按照方法進行轉換code
@Test public void test() { List<String> list = Arrays.asList("a","b","c"); Stream<String> stream = list.stream(); stream=stream.map((x)->x.toUpperCase()); stream.forEach(System.out::println); } 輸出: A B C
flatMap(method)也是接受一個函數做爲參數,可是與map,不一樣的是若是這個函數生成的原本就是流,它會把函數生成流中的元素加到流中對象
//這個函數自己就生成流 public static Stream<Character> toStream(String s){ List<Character> list=new ArrayList<Character>(); char[] chs = s.toCharArray(); for (char c : chs) { list.add(c); } Stream<Character> stream = list.stream(); return stream; } @Test public void test() { List<String> list = Arrays.asList("aaa","bbb","ccc"); Stream<Stream<Character>> stream = //因爲函數自己就生成流,因此流中加入的仍是流 list.stream().map(StreamTest::toStream); //遍歷的時候須要先從流中取出流,在遍歷 stream.forEach((s)->s.forEach(System.out::println)); } //然而咱們可使用flatMap進行改進 @Test public void test() { List<String> list = Arrays.asList("aaa","bbb","ccc"); list.stream().flatMap(StreamTest::toStream).forEach(System.out::println); } 輸出: a a a b b b c c c
當全部元素都匹配時,allMatch(Predicate<? super T> predicate)纔會返回true
@Test public void test() { List<String> list = Arrays.asList("aaa","bbb","ccc"); boolean allMatch = list.stream().allMatch((s)->s.length()>2); System.out.println(allMatch); } 輸出: true
當Stream中任一一個元素匹配時,anyMatch(Predicate<? super T> predicate)返回true
@Test public void test() { List<String> list = Arrays.asList("aaa","bbb","ccc"); boolean anyMatch = list.stream().anyMatch((s)->s.equals("bbb")); System.out.println(anyMatch); } 輸出: true
當Stream中全部的元素都不匹配時,noneMatch(Predicate<? super T> predicate)返回true
@Test public void test() { List<String> list = Arrays.asList("aaa","bbb","ccc"); boolean noneMatch = list.stream().noneMatch((s)->s.equals("ddd")); System.out.println(noneMatch); } 輸出: true
返回當前流中的第一個元素
@Test public void test() { List<Integer> list = Arrays.asList(1,2,3,4,5); Optional<Integer> findFirst = list.stream().findFirst(); System.out.println(findFirst.get()); } 輸出: 1
返回當前流中的任一一個元素
@Test public void test() { List<Integer> list = Arrays.asList(1,2,3,4,5); Optional<Integer> findAny = list.stream().findAny(); System.out.println(findAny.get()); } 輸出: 1 //使用並行流試試 @Test public void test13() { List<Integer> list = Arrays.asList(1,2,3,4,5); Optional<Integer> findAny = list.parallelStream().findAny(); System.out.println(findAny.get()); } 輸出: 3
返回流中的元素個數
@Test public void test14() { List<Integer> list = Arrays.asList(1,2,3,4,5); long count = list.stream().count(); System.out.println(count); } 輸出: 5
返回流中元素的最大值
@Test public void test15() { List<Integer> list = Arrays.asList(1,2,3,4,5); Optional<Integer> max = list.stream().max(Integer::compare); System.out.println(max.get()); } 輸出: 5
返回流中的最小值
@Test public void test16() { List<Integer> list = Arrays.asList(1,2,3,4,5); Optional<Integer> min = list.stream().min(Integer::compare); System.out.println(min.get()); } 輸出: 1
將流中的元素反覆結合獲得一個最終值
@Test public void test() { List<Integer> list = Arrays.asList(1,2,3,4,5); Optional<Integer> reduce = list.stream().reduce(Integer::sum); System.out.println(reduce.get()); Integer reduce2 = list.stream().reduce(0, (x,y)->{ System.out.println(x+"->"+y); return x+y; }); System.out.println(reduce2); } 輸出: 15 0->1 1->2 3->3 6->4 10->5 15
能夠看到當使用(T identity, BinaryOperator
將流轉換成其餘形式
@Test public void test() { List<Integer> list = Arrays.asList(1,2,3,4,5,5); Set<Integer> collect = list.stream().collect(Collectors.toSet()); System.out.println(collect); } 輸出: [1, 2, 3, 4, 5] @Test public void test() { List<Integer> list = Arrays.asList(1,2,3,4,5,5); Optional<Integer> collect = list.stream().collect(Collectors.maxBy(Integer::compareTo)); System.out.println(collect.get()); } 輸出: 5 class Stu{ String name; Integer age; String gender; public Stu(String name, Integer age, String gender) { super(); this.name = name; this.age = age; this.gender = gender; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } @Override public String toString() { return "Stu [name=" + name + ", age=" + age + ", gender=" + gender + "]"; } } //一級分組 @Test public void test() { List<Stu> list = Arrays.asList( new Stu("張三",20,"男"), new Stu("李四",22,"女"), new Stu("王五",18,"男"), new Stu("趙六",20,"女"), new Stu("田七",22,"女") ); Map<String, List<Stu>> collect = list.stream().collect(Collectors.groupingBy(Stu::getGender)); System.out.println(collect); } 輸出: {女=[Stu [name=李四, age=22, gender=女], Stu [name=趙六, age=20, gender=女], Stu [name=田七, age=22, gender=女]], 男=[Stu [name=張三, age=20, gender=男], Stu [name=王五, age=18, gender=男]]} //二級分組 @Test public void test21() { List<Stu> list = Arrays.asList( new Stu("張三",20,"男"), new Stu("李四",22,"女"), new Stu("王五",18,"男"), new Stu("趙六",20,"女"), new Stu("田七",22,"女") ); Map<Integer, Map<String, List<Stu>>> collect = list.stream() .collect(Collectors.groupingBy(Stu::getAge, Collectors.groupingBy(Stu::getGender))); System.out.println(collect); } 輸出: {18={男=[Stu [name=王五, age=18, gender=男]]}, 20={女=[Stu [name=趙六, age=20, gender=女]], 男=[Stu [name=張三, age=20, gender=男]]}, 22={女=[Stu [name=李四, age=22, gender=女], Stu [name=田七, age=22, gender=女]]}} //分區 @Test public void test22() { List<Stu> list = Arrays.asList( new Stu("張三",20,"男"), new Stu("李四",22,"女"), new Stu("王五",18,"男"), new Stu("趙六",20,"女"), new Stu("田七",22,"女") ); Map<Boolean, List<Stu>> collect = list.stream() .collect(Collectors.partitioningBy((e)->((Stu)e).getAge()>20)); System.out.println(collect); } 輸出: {false=[Stu [name=張三, age=20, gender=男], Stu [name=王五, age=18, gender=男], Stu [name=趙六, age=20, gender=女]], true=[Stu [name=李四, age=22, gender=女], Stu [name=田七, age=22, gender=女]]}