Java8 Stream常用API整理

不會打字314發表於2020-11-19

Java8 Stream常用API整理

參考網址:

https://mp.weixin.qq.com/s?__biz=MzU5NDc0MjAyOQ==&mid=2247486114&idx=2&sn=a1baea335d1823c136f12882e640d3e5&chksm=fe7dd4c0c90a5dd6e8bc9fe50cceaf5177cb07c958f10a5a61b28a6fb478ba73ffbca94449d2&mpshare=1&scene=23&srcid=08310qv32Ye6Dy4uM8VFUHY2&sharer_sharetime=1599615340151&sharer_shareid=9d1e76e919cc0b2f3ca23ed1f5ef67a8#rd

前言:

好久之前就像整理stream流相關的知識

  • stream
  • lambda
  • java比較器

這三個知識點要經常的回顧,能學以致用,才能體現java8新特性出來的價值

這篇文章也是為了查漏補缺

參考作者的總結

Java8中有兩大最為重要的改變,第一個是Lambda表示式,另外一個則是Stream API。

流是 Java8 引入的全新概念,它用來處理集合中的資料。

眾所周知,集合操作非常麻煩,若要對集合進行篩選、投影,需要寫大量的程式碼,而流是以宣告的形式操作集合,它就像 SQL 語句,我們只需告訴流需要對集合進行什麼操作,它就會自動進行操作,並將執行結果交給你,無需我們自己手寫程式碼。

在專案中使用 Stream API 可以大大提高效率以及程式碼的可讀性,使我們對資料進行處理的時候事半功倍。

建立測試的實體類

package com.shaoming.java8新特性.stream;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
 * @Auther: shaoming
 * @Date: 2020/11/18 14:18
 * @Description:
 */
@Getter
@Setter
@ToString
@EqualsAndHashCode
public class Employee {

    private int id;
    private String name;
    private int age;
    private double salary;
    private Status status;

    public enum Status {
        FREE, BUSY, VOCATION;
    }

    public Employee() {
    }

    public Employee(String name) {
        this.name = name;
    }

    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Employee(int id, String name, int age, double salary) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public Employee(int id, String name, int age, double salary, Status status) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.salary = salary;
        this.status = status;
    }
    //省略get,set等。。。
}

測試示例

package com.shaoming.java8新特性.stream;

import com.shaoming.java8新特性.stream.Employee.Status;
import com.sun.org.apache.xerces.internal.xs.StringList;
import com.sun.xml.internal.ws.message.EmptyMessageImpl;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Auther: shaoming
 * @Date: 2020/11/18 14:25
 * @Description: 測試java8新特性的
 * stream流相關的知識
 * 參考網址:
 * https://mp.weixin.qq.com/s?__biz=MzU5NDc0MjAyOQ==&mid=2247486114&idx=2&sn=a1baea335d1823c136f12882e640d3e5&chksm=fe7dd4c0c90a5dd6e8bc9fe50cceaf5177cb07c958f10a5a61b28a6fb478ba73ffbca94449d2&mpshare=1&scene=23&srcid=08310qv32Ye6Dy4uM8VFUHY2&sharer_sharetime=1599615340151&sharer_shareid=9d1e76e919cc0b2f3ca23ed1f5ef67a8#rd
 */
public class TestJava8ofStream {
    /**
     * 初始化測試資料
     */
    private static List<Employee> empList = Arrays.asList(
            new Employee(102, "李四", 59, 6666.66, Status.BUSY),
            new Employee(101, "張三", 18, 9999.99, Status.FREE),
            new Employee(103, "王五", 28, 3333.33, Status.VOCATION),
            new Employee(104, "趙六", 8, 7777.77, Status.BUSY),
            new Employee(104, "趙六", 8, 7777.77, Status.FREE),
            new Employee(104, "趙六", 8, 7777.77, Status.FREE),
            new Employee(105, "田七", 38, 5555.55, Status.BUSY));

    /**
     * 1.根據條件篩選
     */
    @Test
    public void test1() {
        Stream<Employee> employeeStream = empList.stream().filter((e) -> {
            return e.getSalary() >= 7000;
        });
        List<Employee> collect = employeeStream.collect(Collectors.toList());
        System.out.println("============" + collect.getClass());//說明預設使用的是ArrayList
        collect.forEach(System.out::println);
    }

    @Test
    public void test2() {
        empList.stream().filter(e -> e.getAge() != 18).collect(Collectors.toList()).forEach(System.out::println);
    }

    /**
     * 2.去重
     */
    //報錯===>轉換成陣列報錯
    @Test
    public void test3() {
        Employee[] empArray = (Employee[]) empList.stream().distinct().toArray();
        for (Employee employee : empArray) {
            System.out.println(employee);
        }

    }

    @Test
    public void test4() {
        List<Employee> employeeList = empList.stream().distinct().collect(Collectors.toList());
        for (Iterator<Employee> iterator = employeeList.iterator(); iterator.hasNext(); ) {
            System.out.println(iterator.next());
        }
    }

    /**
     * 3.擷取流的前n個元素,使用的關鍵方法名稱limit
     */
//      ====>類比於mysql種的limit分頁操作
    @Test
    public void test5() {
        //類比於mysql種查詢salary>5000的前三條資料
        Stream<Employee> stream = empList.stream().filter(e -> e.getSalary() > 5000).limit(3);
        List<Employee> employeeList = stream.collect(Collectors.toList());
        employeeList.forEach(System.out::println);
    }

    //第二種寫法
    @Test
    public void test6() {
        empList.stream().filter(

                (e) -> {
                    return e.getSalary() >= 5000;
                }

        ).limit(3).forEach(System.out::println);
    }

    /**
     * 4.對映map
     */
    @Test
    public void test7() {
        empList.stream().map(e -> e.getName()).forEach(System.out::println);

        empList.stream().map(e -> {
            empList.forEach(i -> {
                i.setName(i.getName() + "111");
            });
            return e;
        }).collect(Collectors.toList()).forEach(System.out::println);
    }

    //使用方法引用的方式進行操作
    @Test
    public void test72() {
        Stream<String> stringStream = empList.stream().map(Employee::getName);
//        System.out.println(stringStream);
        List<String> stringList = stringStream.collect(Collectors.toList());
        System.out.println(stringList);
    }

    //最簡潔的一套方式把list集合的元素的屬性組成一個string型別的list集合
    @Test
    public void test73() {
        empList.stream().map(Employee::getName).collect(Collectors.toList()).forEach(System.out::println);
    }

    /**
     * 5.自然排序 sorted
     */
    @Test
    public void test8() {
        empList.stream().map(Employee::getName).sorted().forEach(System.out::println);
    }

    /**
     * 6.自定義排序 sorted(Compartor comp)
     */
    @Test
    public void test9() {
        empList.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);
    }

    /**
     * 7.匹配元素-返回值為boolean
     * 是否匹配任一元素anyMatch
     */
    @Test
    public void testAnyMatch() {
        boolean b = empList.stream().anyMatch(e -> e.getStatus().equals(Status.BUSY));
        System.out.println("boolean is : " + b);
    }

    /**
     * 8.匹配元素-返回值為boolean
     * 是否匹配所有元素 allMatch
     */
    @Test
    public void testAllMatch() {
        boolean b = empList.stream().allMatch(e -> e.getStatus().equals(Status.BUSY));
        System.out.println("boolean is : " + b);
    }

    /**
     * 9.匹配元素-返回值為boolean
     * 是否未匹配所有元素 noneMatch
     */
    @Test
    public void testNoneMatch() {
        boolean b = empList.stream().noneMatch(e -> e.getStatus().equals(Status.BUSY));
        System.out.println("boolean is : " + b);
    }

    /**
     * 10.返回第一個元素
     * finFirst
     */
    @Test
    public void testFindfirst() {
        Optional<Employee> op = empList.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())).findFirst();
        if (op.isPresent()) {
            System.out.println("first employee name is : " + op.get().getName().toString());
        }
    }

    //測試Compare
    @Test
    public void testCompare() {
        int compare = Integer.compare(2, 2);
        System.out.println(compare);
    }

    //測試CompareTo
    @Test
    public void testCompareTo() {
        Double d1 = 222.0;
        Double d2 = 333.0;
        int i = d1.compareTo(d2);
        System.out.println(i);
    }

    //在返回第一個元素前先過濾記錄先filter在findfirst
    @Test
    public void testFindFirstAndOther() {
        Optional<Employee> op = empList.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())).filter(e -> !e.getName().equals("王五")).findFirst();
        if (op.isPresent()) {
            System.out.println("first employee name is : " + op.get().getName());
        }
    }

    /**
     * 11.返回流中的任意元素
     * findAny
     */
    @Test
    public void testFindAll() {
        Optional<Employee> op = empList.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))
                .findAny();
        if (op.isPresent()) {
            System.out.println("any employee name is : " + op.get().getName().toString());
        }
    }

    //小測試
    //定義一個string型別的list集合,然後返回裡面任意的一個元素
    @Test
    public void testFindAll2() {
        List<String> stringList = Arrays.asList(
                "cccc", "zzzz", "PHP", "c", "c++"
        );
        Optional<String> any = stringList.stream().findAny();
        System.out.println(any.get());
    }

    /**
     * 12.返回總記錄數
     * Count()
     */
    //===>類比於mysql中的count(1)函式
    @Test
    public void testCount() {
        long count = empList.stream().filter(
                e -> e.getStatus().equals(Status.FREE)
        ).count();
        System.out.println("Count is :" + count);
    }

    @Test
    public void testCountAndOther() {
        List<String> stringList = Arrays.asList(
                "cccc", "zzzz", "PHP", "c", "c++"
        );
        long count = stringList.stream().filter(s -> s.length() > 3).count();
        System.out.println("字串字元大於3個的數量   " + count);
    }

    /**
     * 13.返回流中的最大值
     * max()
     */
    //相當於mysql的max()函式
    @Test
    public void testMax() {
        Optional<Double> max = empList.stream().map(Employee::getSalary).max(Double::compare);
        System.out.println(max.get());
    }

    /**
     * 14.返回流中的最小值
     * min()
     */
    @Test
    //相當於mysql的min()函式
    public void testMin() {
        Optional<Employee> min = empList.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        System.out.println("員工salay最小的員工資訊");
        System.out.println(min.get());
    }

    /**
     * 15.將元素收集到list裡
     * Collectors.toList()
     */
    //把流中的元素收集到list裡
    @Test
    public void testCollectorstoList() {
        empList.stream().collect(Collectors.toList()).forEach(System.out::println);
    }

    //將emplist中的employee的每個name放到String型別的集合中
    @Test
    public void testCollectorstoListOftype() {
        empList.stream().map(e -> e.getName()).collect(Collectors.toList()).forEach(
                e -> System.out.println("員工的姓名為:" + e)
        );
    }

    @Test
    public void testCollectorstoListOftypeOtherOpertion() {
        List<String> stringList = new ArrayList<>();
        empList.stream().map(e -> e.getName()).collect(Collectors.toList()).forEach(
                (e) -> {
                    if (e.contains("趙")) {
                        stringList.add("該員工的姓名為:" + e);
                    }
                }
        );
        stringList.forEach(System.out::println);
        System.out.println("去重之後的名字列表為:");
        stringList.stream().distinct().collect(Collectors.toList()).forEach(System.out::println);
    }

    /**
     * 16.將元素收集到set裡,Collection.toSet()
     */
    @Test
    public void testCollectorsToSet() {
        empList.stream().map(Employee::getName).collect(Collectors.toSet()).forEach(System.out::println);
    }

    //以上操作等價於  ===> 先給String的list集合去重,然後放到list裡面
    @Test
    public void testCollectorsToListEqualsCollectorsToSet() {
        empList.stream().map(Employee::getName).distinct().collect(Collectors.toList()).forEach(System.out::println);
    }

    /**
     * 17.把流中的元素收集到新建立的集合裡
     * Collections.toCollection(HashSet::new)
     */
    @Test
    public void testToCollectionNew() {
        HashSet<Employee> employees = empList.stream().collect(Collectors.toCollection(HashSet::new));
    }

    /**
     * 18.根據比較器選擇最大值
     * Collectors.maxBy()
     */
    @Test
    public void testCollectorsMaxBy() {
        Optional<Double> max = empList.stream().map(Employee::getSalary).collect(Collectors.maxBy(Double::compare));
        System.out.println(max.get());
    }

    /**
     * 19.根據比較器選擇最小值。
     * 根據比較器選擇最小值 Collectors.minBy()
     */
    @Test
    public void testCollectorsMinBy() {
        Optional<Double> max = empList.stream().map(Employee::getSalary).collect(Collectors.minBy(Double::compare));
        System.out.println(max.get());
    }

    /**
     * 20.對流中元素的某個欄位求和
     * Collectors.summingDouble()
     */
    //===>類比於mysql中的sum()函式
    @Test
    public void testCollectionsSummingDouble() {
        Double sum = empList.stream().collect(Collectors.summingDouble(Employee::getSalary));
        System.out.println("總薪資為: " + sum);
    }

    /**
     * 21.對流中的某個欄位求平均值
     * Collectors.averagingDouble()
     */
    @Test
    public void testCollectorsAveraginDouble() {
        Double avg = empList.stream().collect(Collectors.averagingDouble(Employee::getSalary));
        System.out.println("薪資平均值為:" + avg);
    }

    /**
     * 22.分組,類似sql的groupby
     * Collectors.groupingBy
     */
    @Test
    public void testCollectorsGroupBy() {
        Map<Status, List<Employee>> statusListMap = empList.stream().collect(Collectors.groupingBy(Employee::getStatus));
        statusListMap.forEach((k,v)->{
            System.out.println(k+" "+v);
        });
    }
    /**
     * 23.多級分組
     */
    @Test
   public  void testCollectorsGroupingBy1() {
        Map<Status, Map<String, List<Employee>>> map = empList.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);
    }
    /**
     * 24.字元竄拼接
     */
    @Test
    public void testCollectorsJoining() {
        String str = empList.stream().map(Employee::getName).collect(Collectors.joining(",", "----", "----"));
        System.out.println(str);
    }
}




相關文章