Java 8 Lambda與Stream的使用例子

首先創建一個實體類用來進行一些操作。 

import java.util.Objects;

public class Employee {

    public Employee() {
        super();
    }

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

    public Employee(String name,Integer ... integers){
        this.name = name;
        for (Integer is:integers){

        }
    }

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

    @Override
    public String toString() {
        return "com.java8.Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employee employee = (Employee) o;
        return
                salary == employee.salary;
    }

    @Override
    public int hashCode() {
        return Objects.hash(salary);
    }

    private String name;
    private int age;
    private int salary;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }
}

對實體類操作的小例子:

import com.interfaces.MyFun;
import com.interfaces.MyFunction;
import com.interfaces.MyFunction1;
import com.sun.istack.internal.NotNull;
import org.junit.Test;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;

import javax.naming.Name;
import java.util.*;
import java.util.function.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/***
 * 函數式接口:若接口中只有一個抽象方法的接口,叫做是函數式接口。可以用  @FunctionInterface 修飾一下,可以檢查是否是函數式接口
 *
 *
 *
 *
 */
public class TestLambda {

    List<Employee> employees = Arrays.asList(
            new Employee("張三", 20, 1),
            new Employee("李四", 30, 2),
            new Employee("王五", 20, 3),
            new Employee("麻六", 50, 4),
            new Employee("錢七", 60, 5),
            new Employee("錢七", 60, 6),
            new Employee("小明", 70, 7)
    );

    @Test
    public void test() {
        employees.stream().filter(employee -> employee.getAge() > 30).forEach(System.out::println);
        employees.stream().map(Employee::getName).sorted().forEach(System.out::print);
        employees.stream().filter(employee -> employee.getAge() > 50).limit(2).parallel().forEach(System.out::println);
        System.out.println();
        employees.stream().filter(employee -> employee.getSalary() > 80000).forEach(System.out::println);
        System.out.println("取名字-------------------------------------");
        List<String> stringList = employees.stream().map(Employee::getName).collect(Collectors.toList());
        stringList.stream().forEach(System.out::println);
        System.out.println("根據工資排序-------------------------------------------");
        employees.sort(Comparator.comparing(employee -> (employee.getSalary())));
        employees.stream().forEach(System.out::println);
    }

    /**
     * lambda表達式無參無返回值
     */
    @Test
    public void lambda() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("hello world!");
            }
        };
        runnable.run();
        System.out.println("----------------------------------------");
        Runnable runnable1 = () -> {
            System.out.println("hello lambda!");
            System.out.println("lambda 箭頭 後面可以寫成方法體!");
        };
        runnable1.run();
    }

    /**
     * lambda 有一個參數無返回值,若只有一個參數的時候小括號可以不寫  x->System.out.println(x);
     */
    @Test
    public void lambda1() {
        Consumer<String> con = (string) -> System.out.println(string + "  " + string.length());
        con.accept("今天回家的時候下雨了!");
    }

    /**
     * lambda 如果有多個參數,並且有返回參數
     */
    @Test
    public void lambda2() {
        Comparator<Integer> com = (x, y) -> {
            System.out.println("函數式接口!");
            return Integer.compare(x, y);
        };
        System.out.println(com.compare(12, 15));
        //多個參數並且有返回值的情況下,如果方法體內只有一條語句,則返回值和方法體都不寫
        Comparator<Integer> com1 = (x, y) -> Integer.compare(x, y);
    }

    @Test
    public void lambda3() {
        Integer returnNum = operation(100, num -> num * 2);
        System.out.println(returnNum);
        System.out.println(operation(1000, y -> y * 2 + 100));
    }

    public Integer operation(Integer num, MyFun mf) {
        return mf.getValue(num);
    }

    /***
     * 根據年齡排序,如果年齡相等那就按照名稱排序
     */
    @Test
    public void lambda4() {
        Collections.sort(employees, (e1, e2) -> {
            if (e1.getAge() == e2.getAge()) {
                return e1.getName().compareTo(e2.getName());
            } else {
                return -Integer.compare(e1.getAge(), e2.getAge());
            }
        });
        for (Employee e : employees) {
            System.out.println(e.toString());
        }
    }

    /**
     * 對一個字符串進行處理
     */
    @Test
    public void lambda5() {
        String string = strHandle("   今天天   氣真不錯   ", str -> str.trim());
        System.out.println(string);
        String sh = strHandle("abcdasdfjlsadj", str -> str.toUpperCase());
        System.out.println("轉換字母爲大寫:" + sh);
    }

    public String strHandle(String str, MyFunction mf) {
        return mf.getValue(str);
    }

    @Test
    public void lambda6() {
        longOp(1024L, 1010L, (x, y) -> x + y);
    }

    public void longOp(Long t1, Long t2, MyFunction1<Long, Long> mf) {
        System.out.println("lambda 求兩個數之和:" + t1 + "+" + t2 + "  " + mf.getValue(t1, t2));
    }

    /**
     * 消費型接口 沒有返回值
     */
    @Test
    public void lamgda7() {
        happy(100000, m -> System.out.println("今天消費了  " + m + "  元!"));
    }

    public void happy(double money, Consumer<Double> con) {
        con.accept(money);
    }

    /**
     * 供給型接口
     */
    @Test
    public void lambda8() {
        List<Integer> integerList = getNumList(20, () -> {
            return (int) (Math.random() * 100);
        });
        System.out.println("產生了  " + integerList.stream().count() + "  個數");
        integerList.forEach(System.out::println);
    }

    public List<Integer> getNumList(int num, Supplier<Integer> integerSupplier) {
        List<Integer> nums = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            nums.add(integerSupplier.get());
        }
        return nums;
    }

    /***
     * 函數型接口
     */
    @Test
    public void lambda9() {
        System.out.println("使用函數式接口來顯示我輸入的字符串長度:" + getValue("今天天氣挺不錯的,可惜沒有出去找女朋友!", s -> s.length()));
    }

    public int getValue(String str, Function<String, Integer> mf) {
        return mf.apply(str);
    }

    /**
     * 斷言型接口
     */

    @Test
    public void lambda10() {
        List<String> strings = filterString(employees, employee -> employee.getSalary() > 50000);
        strings.forEach(System.out::println);
    }

    public List<String> filterString(List<Employee> employees, Predicate<Employee> pre) {
        List<String> stringList = new ArrayList<>();
        for (Employee employee : employees
        ) {
            if (pre.test(employee)) {
                stringList.add(employee.toString());
            }
        }
        return stringList;
    }

    /**
     * 對象::實例方法名
     */
    @Test
    public void lambda11() {
        Consumer<String> con = System.out::println;
        con.accept("今天星期天了,還是不知道怎麼和女性朋友聊天!");

        Supplier<Integer> supplier = () -> {
            int age = 0;
            for (Employee e : employees) {
                if (e.getSalary() > 50000)
                    age = e.getAge();
            }
            return age;
        };
        System.out.println(supplier.get());

        Supplier<Integer> sup = employees.stream().findFirst().get()::getAge;
        System.out.println(sup.get());
    }

    /**
     * 類::靜態方法
     */
    @Test
    public void lambda12() {
        //第一種寫法
        Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
        //第二種寫法
        Comparator<Integer> com = Integer::compareTo;
        System.out.println(com.compare(123, 213));
    }

    /**
     * 類::實例方法名
     */
    @Test
    public void lambda13() {
        //第一種寫法
        BiPredicate<String, String> biPredicate = (x, y) -> x.equals(y);
        System.out.println(biPredicate.test("今天天氣不錯", "今天 天氣不錯"));
        //第二種寫法
        BiPredicate<String, String> biPredicate1 = String::equals;
        System.out.println(biPredicate1.test("今天天氣不錯", "今天 天氣不錯"));
    }

    /***
     * 構造器引用
     */
    @Test
    public void lambda14() {
        //第一種寫法
        Supplier<Employee> supplier = () -> new Employee();
        System.out.println(supplier.get());
        //第二種寫法
        Supplier<Employee> employeeSupplier = Employee::new;
        System.out.println(employeeSupplier.get());

        Function<String, String> function = (x) -> new Employee(x).toString();
        System.out.println(function.apply("小明"));
        Function<String, Employee> function1 = Employee::new;
        System.out.println(function1.apply("小紅"));
    }

    /***
     * 數組引用
     */
    @Test
    public void lambda15() {
        Function<Integer, String[]> function = (x) -> new String[x];
        System.out.println(function.apply(10).length);
        Function<Integer, String[]> function1 = String[]::new;
        System.out.println(function1.apply(12).length);
    }

    /**
     * 創建stream
     */
    @Test
    public void lambda16() {
        //1、通過Conllection 系列集合提供Stream() 或 parallelStream()
        List<String> strings = new ArrayList<>();
        Stream<String> stringStream = strings.stream();
        //2、通過Arrays中的靜態方法 獲取數組流
        Employee[] employees = new Employee[10];
        Stream<Employee> employeeStream = Arrays.stream(employees);
        //3、通過stream類中的靜態方法of
        Stream<String> stringStream1 = Stream.of("今天", "明天", "後天");
        //4、創建無限流
        //迭代
        Stream<Integer> integerStream = Stream.iterate(0, (x) -> x + 2);
        integerStream.limit(10).forEach(System.out::println);
        //生成
        Stream<Double> doubleStream = Stream.generate(() -> Math.random());
        doubleStream.limit(5).forEach(System.out::println);
    }

    @Test
    public void lambda17() {
        employees.stream().forEach(System.out::println);
        System.out.println();
        //filter的使用
        employees.stream().filter(e -> e.getAge() > 30).forEach(System.out::println);
        System.out.println();
        //skip的使用
        employees.stream().filter(e -> e.getAge() > 30).skip(2).forEach(System.out::println);
        System.out.println();
        //limit的使用
        employees.stream().filter(e -> e.getAge() > 30).limit(2).forEach(System.out::println);
        System.out.println();
        //在使用distinct方法的時候需要重寫比較對象的hashCode和equals
        employees.stream().distinct().forEach(System.out::println);
        //map的使用
        System.out.println("map的使用---------------------");
        employees.stream().map(e -> {
            //首先對集合對象的工資進行操作,然後再把修改後的工資信息放入到該對象中
            e.setSalary(e.getSalary() + 100000);
            return e;
        }).forEach(System.out::println);
    }

    /**
     * flatmap
     */
    @Test
    public void lambda18() {
        List<String> strings = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
        strings.stream().forEach(s -> {
            System.out.println(s.toUpperCase());
        });
        strings.stream().flatMap(TestLambda::filterCharacter).forEach(System.out::println);
    }

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

    /**
     * sort
     */
    @Test
    public void lambda19() {
        List<String> lists = Arrays.asList("eee", "aaa", "bbb", "ddd", "ccc");
        lists.stream().sorted().forEach(System.out::println);
        long st = System.currentTimeMillis();
        employees.parallelStream().sorted((e1, e2) -> {
            if (e1.getSalary() == e2.getSalary()) {
                return e1.getName().compareTo(e2.getName());
            } else {
                return e1.getSalary() - e2.getSalary();
            }
        }).forEach(System.out::println);
        System.out.println(System.currentTimeMillis() - st);

        long st1 = System.currentTimeMillis();
        employees.stream().sorted((e1, e2) -> {
            if (e1.getSalary() == e2.getSalary()) {
                return e1.getName().compareTo(e2.getName());
            } else {
                return e1.getSalary() - e2.getSalary();
            }
        }).forEach(System.out::println);
        System.out.println(System.currentTimeMillis() - st1);
    }

    /**
     * allMatch檢查是否匹配所有元素
     * anyMatch檢查是否至少匹配一個元素
     * noneMatch檢查是否沒有匹配所有元素
     * findFirst返回第一個元素
     * findAny返回當前流中的任意元素
     * count返回流中的總個數
     * max返回流中最大值
     * min返回六中最小值
     */
    @Test
    public void lambda20() {
        employees.stream().forEach(System.out::println);
        boolean ballMath = employees.stream().allMatch(employee -> employee.getName().equals("張三"));
        System.out.println("allMatch檢查是否匹配所有元素:" + ballMath);
        boolean banyMatch = employees.stream().anyMatch(employee -> employee.getName().equals("張三"));
        System.out.println("anyMatch檢查是否至少匹配一個元素:"+banyMatch);
        boolean bnoneMatch = employees.stream().noneMatch(employee -> employee.getName().equals("小紅"));
        System.out.println("noneMatch檢查是否沒有匹配所有元素:"+bnoneMatch);
        Optional<Employee> op = employees.parallelStream().sorted((e1,e2)->-Double.compare(e1.getSalary(),e2.getSalary())).findFirst();
        System.out.println(op.get());
        Optional op1 = employees.parallelStream().findAny();
        System.out.println(op1.get());
        long count = employees.parallelStream().count();
        System.out.println(count);
        Optional opmax = employees.parallelStream().max((e1,e2)->e1.getSalary()-e2.getSalary());
        Optional<Employee> opmax1 = employees.parallelStream().max((e1,e2)->Double.compare(e1.getSalary(),e2.getSalary()));
        System.out.println(opmax.get()+"   "+opmax1.get());
        Optional opmin = employees.parallelStream().min((e1,e2)->e1.getAge()-e2.getAge());
        Optional<String> opmin1 = employees.parallelStream().map(employee -> employee.getName()).min(String::compareTo);
        System.out.println(opmin.get()+"   "+opmin1.get());
    }

    /**
     * reduce 規約 將流中的元素反覆集合起來,得到一個值
     */
    @Test
    public void lambda21(){
        List<Integer> integers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        Integer sum = integers.parallelStream().reduce(0,(x,y)->x+y);
        System.out.println(sum);
        Optional sumSalary = employees.parallelStream().map(Employee::getSalary).reduce(Integer::sum);
        System.out.println(sumSalary.get());
    }

    /**
     * collect 收集 把名字收集到指定的集合中
     */
    @Test
    public void lambda22(){
        List<String> names = employees.parallelStream().map(Employee::getName).collect(Collectors.toList());
        names.forEach(System.out::println);
        System.out.println();
        //去重的兩種方法
            //第一種使用distinct
        List<String> distinctNames = employees.parallelStream().map(Employee::getName).distinct().collect(Collectors.toList());
        distinctNames.forEach(System.out::print);
            //第二種使用set
        System.out.println();
        Set<String> strings = employees.parallelStream().map(Employee::getName).collect(Collectors.toSet());
        strings.forEach(System.out::println);

        System.out.println("取出指定的值放入到指定的對象中去");
        ArrayList<String> arrayList = employees.parallelStream().map(Employee::getName).collect(Collectors.toCollection(ArrayList::new));
        arrayList.forEach(System.out::println);
        //集合的總數
        long count = employees.parallelStream().collect(Collectors.counting());
        System.out.println("使用collect獲取集合的大小:"+count);
        //獲取平均值
        Double avgSalary = employees.parallelStream().collect(Collectors.averagingDouble(Employee::getSalary));
        System.out.println("使用collect獲取所有人的平均工資:"+avgSalary);
        //獲取工資的總和
        Double salarySum = employees.parallelStream().collect(Collectors.summingDouble(Employee::getSalary));
        System.out.println("工資總和:"+salarySum);
        DoubleSummaryStatistics s = employees.parallelStream().collect(Collectors.summarizingDouble(Employee::getSalary));
        System.out.println("獲取工資的總和:"+s.getSum()+"  平均值:"+s.getAverage()+" 最大值:"+s.getMax()+" 最小值:"+s.getMin()+" 數量:"+s.getCount());
        //分組
        System.out.println("集合進行分組------------------");
        Map<String,List<Employee>> hp = employees.parallelStream().collect(Collectors.groupingBy(Employee::getName));
        System.out.println(hp);
        //多級分組
        Map<String,Map<Integer,List<Employee>>> hs = employees.parallelStream().collect(Collectors.groupingBy(Employee::getName,Collectors.groupingBy(Employee::getAge)));
        System.out.println("多級分組:"+hs);
        //分區
        Map<Boolean,List<Employee>> parts  = employees.parallelStream().collect(Collectors.partitioningBy(employee -> employee.getAge()<50));
        System.out.println("分區:"+parts);
        //連接字符串
        String sname = employees.parallelStream().map(Employee::getName).collect(Collectors.joining(","));
        System.out.println("連接字符串:"+sname);

    }

    /**
     * 給定一個數字列表,返回這個列表中每個數字的平方
     */
    @Test
    public void lambda23(){
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        List<Integer> list1 = list.parallelStream().map(s -> (int)Math.pow(s,2)).collect(Collectors.toList());
        list1.stream().forEach(System.out::println);
    }
    /**
     * 怎樣用map和reduce方法統計一個集合中有多少對象
     */
    @Test
    public void lambda24(){
        Optional<Integer> optionalInteger = employees.stream().map(e -> 1).reduce(Integer::sum);
        System.out.println(optionalInteger.get());
        Long count = employees.stream().count();
        System.out.println(count);
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章