java8新特性-Stream


 

Java8中的Collection接口被擴展,提供了兩個獲取流的方法: 

default Stream<E> stream() :返回一個順序流 

default Stream<E> parallelStream() :返回一個並行流 

1創建

1. Collection 提供了兩個方法  stream() 與 parallelStream()

List<String> list = new ArrayList<>();
Stream<String> stream = list.stream(); //獲取一個順序流
Stream<String> parallelStream = list.parallelStream(); //獲取一個並行流

2. 通過 Arrays 中的 stream() 獲取一個數組流

Integer[] nums = new Integer[10];
Stream<Integer> stream1 = Arrays.stream(nums);

3通過 Stream 類中靜態方法 of()

    Stream<Integer> stream2 = Stream.of(1,2,3,4,5,6);

4創建無限流

//迭代
        Stream<Integer> stream3 = Stream.iterate(0, (x) -> x + 2).limit(10);
        stream3.forEach(System.out::println);

5

    //生成
        Stream<Double> stream4 = Stream.generate(Math::random).limit(2);
        stream4.forEach(System.out::println);

 2中間操作

篩選與切片

filter——接收 Lambda , 從流中排除某些元素。

limit——截斷流,使其元素不超過給定數量。

skip(n) —— 跳過元素,返回一個扔掉了前 n 個元素的流。若流中元素不足 n 個,則返回一個空流。與 limit(n) 互補

distinct——篩選,通過流所生成元素的 hashCode() 和 equals() 去除重復元素

 

所有的中間操作不會做任何的處理,
只有當做終止操作時,所有的中間操作會一次性的全部執行,稱為“惰性求值”

 

 

    //外部迭代
    @Test
    public void test3(){
        Iterator<Employee> it = emps.iterator();
        
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }

filter——接收 Lambda , 從流中排除某些元素。

 

@Test
    public void test4(){
        emps.stream()
            .filter((e) -> {
                System.out.println("短路!"); // &&  ||
                return e.getSalary() >= 5000;
            }).limit(3)
            .forEach(System.out::println);
    }
@Test
    public void test5(){
        emps.parallelStream()
            .filter((e) -> e.getSalary() >= 5000)
            .skip(2)
            .forEach(System.out::println);
    }
    @Test
    public void test6(){
        emps.stream()
            .distinct()
            .forEach(System.out::println);
    }

 

映射

 

map——接收 Lambda , 將元素轉換成其他形式或提取信息。接收一個函數作為參數,該函數會被應用到每個元素上,並將其映射成一個新的元素。

flatMap——接收一個函數作為參數,將流中的每個值都換成另一個流,然后把所有流連接成一個流

 

    @Test
    public void test1(){
        Stream<String> str = emps.stream()
            .map((e) -> e.getName());
        
        System.out.println("-------------------------------------------");
        
        List<String> strList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
        
        Stream<String> stream = strList.stream()
               .map(String::toUpperCase);
        
        stream.forEach(System.out::println);
        
        Stream<Stream<Character>> stream2 = strList.stream()
               .map(TestStreamAPI1::filterCharacter);
        
        stream2.forEach((sm) -> {
            sm.forEach(System.out::println);
        });
        
        System.out.println("---------------------------------------------");
        
        Stream<Character> stream3 = strList.stream()
               .flatMap(TestStreamAPI1::filterCharacter);
        
        stream3.forEach(System.out::println);
    }

    public static Stream<Character> filterCharacter(String str){
        List<Character> list = new ArrayList<>();
        
        for (Character ch : str.toCharArray()) {
            list.add(ch);
        }
        
        return list.stream();
    }

sorted()——自然排序(Comparable

sorted(Comparator com)——定制排序

@Test
    public void test2(){
        emps.stream()
            .map(Employee::getName)
            .sorted()
            .forEach(System.out::println);
        
        System.out.println("------------------------------------");
        
        emps.stream()
            .sorted((x, y) -> {
                if(x.getAge() == y.getAge()){
                    return x.getName().compareTo(y.getName());
                }else{
                    return Integer.compare(x.getAge(), y.getAge());
                }
            }).forEach(System.out::println);
    }

3終止操作(終端操作)

 

allMatch——檢查是否匹配所有元素

anyMatch——檢查是否至少匹配一個元素

noneMatch——檢查是否沒有匹配的元素

findFirst——返回第一個元素

findAny——返回當前流中的任意元素

count——返回流中元素的總個數

max——返回流中最大值

min——返回流中最小值

歸約:reduce(T identity, BinaryOperator) / reduce(BinaryOperator) ——可以將流中元素反復結合起來,得到一個值。

收集:collect——將流轉換為其他形式。接收一個 Collector接口的實現,用於給Stream中元素做匯總的方法,轉換list,set等

 

 allMatch——檢查是否匹配所有元素

boolean bl = emps.stream()
                .allMatch((e) -> e.getStatus().equals(Status.BUSY));
            
            System.out.println(bl);

anyMatch——檢查是否至少匹配一個元素

boolean bl1 = emps.stream()
                .anyMatch((e) -> e.getStatus().equals(Status.BUSY));
            
            System.out.println(bl1);

noneMatch——檢查是否沒有匹配的元素

boolean bl2 = emps.stream()
                .noneMatch((e) -> e.getStatus().equals(Status.BUSY));
            
            System.out.println(bl2);

findAny——返回當前流中的任意元素

 

Optional<Employee> op2 = emps.parallelStream()
            .filter((e) -> e.getStatus().equals(Status.FREE))
            .findAny();
        
        System.out.println(op2.get());

findFirst——返回第一個元素

Optional<Employee> op = emps.stream()
            .sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))
            .findFirst();
        
        System.out.println(op.get());

count——返回流中元素的總個數

 

long count = emps.stream()
                         .filter((e) -> e.getStatus().equals(Status.FREE))
                         .count();
        
        System.out.println(count);

 

max——返回流中最大值

min——返回流中最小值

Optional<Double> op = emps.stream()
            .map(Employee::getSalary)
            .max(Double::compare);
        
        System.out.println(op.get());
        
        Optional<Employee> op2 = emps.stream()
            .min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        
        System.out.println(op2.get());

注意:流進行了終止操作后,不能再次使用

@Test
    public void test4(){
        Stream<Employee> stream = emps.stream()
         .filter((e) -> e.getStatus().equals(Status.FREE));
        
        long count = stream.count();
        
        stream.map(Employee::getSalary)
            .max(Double::compare);
    }

會報錯

 

歸約:reduce(T identity, BinaryOperator) / reduce(BinaryOperator) ——可以將流中元素反復結合起來,得到一個值。

    @Test
    public void test1(){
        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);
        
        System.out.println("----------------------------------------");
        
        Optional<Double> op = emps.stream()
            .map(Employee::getSalary)
            .reduce(Double::sum);
        
        System.out.println(op.get());
    }

收集:collect——將流轉換為其他形式。接收一個 Collector接口的實現,用於給Stream中元素做匯總的方法

 

    @Test
    public void test3(){
        List<String> list = emps.stream()
            .map(Employee::getName)
            .collect(Collectors.toList());
        
        list.forEach(System.out::println);
        
        System.out.println("----------------------------------");
        
        Set<String> set = emps.stream()
            .map(Employee::getName)
            .collect(Collectors.toSet());
        
        set.forEach(System.out::println);

        System.out.println("----------------------------------");
        
        HashSet<String> hs = emps.stream()
            .map(Employee::getName)
            .collect(Collectors.toCollection(HashSet::new));
        
        hs.forEach(System.out::println);
    }

 

 

    @Test
    public void test4(){
        Optional<Double> max = emps.stream()
            .map(Employee::getSalary)
            .collect(Collectors.maxBy(Double::compare));
        
        System.out.println(max.get());
        
        //最小值
        Optional<Employee> op = emps.stream()
            .collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
        
        System.out.println(op.get());
        
        //總和
        Double sum = emps.stream()
            .collect(Collectors.summingDouble(Employee::getSalary));
        
        System.out.println(sum);
        
        //平均值
        Double avg = emps.stream()
            .collect(Collectors.averagingDouble(Employee::getSalary));
        
        System.out.println(avg);
        
        //統計
        Long count = emps.stream()
            .collect(Collectors.counting());
        
        System.out.println(count);
        
        System.out.println("--------------------------------------------");
        
        DoubleSummaryStatistics dss = emps.stream()
            .collect(Collectors.summarizingDouble(Employee::getSalary));
        
        System.out.println(dss.getMax());
    }

分組

//分組
    @Test
    public void test5(){
        Map<Status, List<Employee>> map = emps.stream()
            .collect(Collectors.groupingBy(Employee::getStatus));
        
        System.out.println(map);
    }

 

多級分組
//多級分組
    @Test
    public void test6(){
        Map<Status, Map<String, List<Employee>>> map = emps.stream()
            .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
                if(e.getAge() >= 60)
                    return "老年";
                else if(e.getAge() >= 35)
                    return "中年";
                else
                    return "成年";
            })));
        
        System.out.println(map);
    }

 

分區 :按true/false

    //分區
    @Test
    public void test7(){
        Map<Boolean, List<Employee>> map = emps.stream()
            .collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000));
        
        System.out.println(map);
    }

拼接

    @Test
    public void test8(){
        String str = emps.stream()
            .map(Employee::getName)
            .collect(Collectors.joining("," , "----", "----"));
        
        System.out.println(str);
    }

 

 

 

 並行流

 是對fork/join的優化

參考:fork/join

 

.parallel(),做數字累加操作,會啟用多線程,cpu高負載;
    @Test
    public void test3(){
        long start = System.currentTimeMillis();
        
        Long sum = LongStream.rangeClosed(0L, num)
                             .parallel()
                             .sum();
        
        System.out.println(sum);
        
        long end = System.currentTimeMillis();
        
        System.out.println("test3耗費的時間為: " + (end - start));
    }

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM