java基礎-8 函數式編程

函數式接口

 

  • 函數式接口概述

  • 函數式接口作爲方法的參數

public class Test {
    public static void main(String[] args) {
        //匿名內部類
        startThread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "線程啓動了!");
            }
        });
        //lambda表達式
        startThread(() ->System.out.println(Thread.currentThread().getName() + "線程啓動了!"));

    }

    public static void startThread(Runnable rne) {
        new Thread(rne, "線程1").start();
    }
}
  • 函數式接口作爲方法的返回值

public class Test {
    public static void main(String[] args) {
        //函數式接口作爲方法的返回值
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("bbb");
        arrayList.add("c");
        arrayList.add("aa");
        arrayList.add("dddd");

        System.out.println("排序前: " + arrayList);
        //sort排序
        //Collections.sort(arrayList);  //排序後: [aa, bbb, c, dddd]
        //自定義比較器(按長度排序)
        Collections.sort(arrayList, getComparator());
        System.out.println("排序後: " + arrayList);
    }

    public static Comparator<String> getComparator(){
        //匿名內部類的方式實現
/*        return  new Comparator<String>(){
            @Override
            public int compare(String str1, String str2) {
                return str1.length() - str2.length();
            }
        };
*/
        //lambada表達式的方式實現
        return (str1, str2)->str1.length() - str2.length();
    }
}
  • 常用函數式接口

Supplier

Supplier接口也被稱爲生產型接口,如果我們指定了接口的泛型是什麼類型,那麼接口中的get方法就會生產什麼類型的數據供我們使用。

 常用方法只有一個無參的方法

方法名

說明

T get()

按照某種實現邏輯(Lambda表達式實現)返回一個數據

public class Test {
    public static void main(String[] args) {
        //Supplier生產數據接口
        String str = getString(()->"李茂貞");
        System.out.println(str);

        Integer num = getInteger(()-> 25);
        System.out.println(num);

    }

    //定義一個方法返回一個字符串
    public static String getString(Supplier<String> supp){
        return supp.get();
    }

    //定義一個方法返回一個數字
    public static Integer getInteger(Supplier<Integer> supp){
        return supp.get();
    }
}

public class Test {
    public static void main(String[] args) {
        //Supplier生產數據接口
        int[] arr = {1, 5, 8, 3, 6, 9};
        int num = getMax(() -> {
            int max = arr[0];
            for (int i : arr) {
                if (i > max) {
                    max = i;
                }
            }
            return max;
        });
        System.out.println(num);

    }

    //定義一個方法返回一個字符串
    public static int getMax(Supplier<Integer> supp) {
        return supp.get();
    }
}
  • 常用函數式接口之Consumer

Consumer接口也被稱爲消費型接口,它消費的數據的數據類型由泛型指定  常用方法

Consumer:包含兩個方法

方法名

說明

void accept(T t)

對給定的參數執行此操作

default Consumer andThen(Consumer after)

返回一個組合的Consumer,依次執行此操作,然後執行 after操作

 

public class Test {
    public static void main(String[] args) throws IOException {
        /*Consumer<T>:包含兩個方法
        void accept​(T t):對給定的參數執行此操作
        default Consumer<T> andThen​(Consumer after):返回一個組合的 Consumer,依次執行此操作,然後執行 after操作
        Consumer<T>接口也被稱爲消費型接口,它消費的數據的數據類型由泛型指定*/

        //消費一個字符串,反轉該字符串
/*        operatorString("李茂貞", (s) -> {
            System.out.println(new StringBuilder(s).reverse().toString());
        });*/
        //匿名內部類
        operatorString("往後餘生", new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(new StringBuilder(s).reverse().toString());
            }
        }, new Consumer<String>() {
            @Override
            public void accept(String s) {
                String subStr = s.substring(0, 2);
                System.out.println(subStr);
                System.out.println(subStr.length());
            }
        });
        System.out.println("---------------------");
        //lambda表達式
        operatorString("李茂貞", s -> System.out.println(new StringBuilder(s).reverse().toString()));
        System.out.println("---------------------");
        //消費一個字符串,反轉該字符串,切割字符串
        operatorString("往後餘生", s -> System.out.println(new StringBuilder(s).reverse().toString()),
                s -> {
                    String subStr = s.substring(0, 2);
                    System.out.println(subStr);
                    System.out.println(subStr.length());
                });
    }

    //定義一個方法,消費一個字符串兩次
    private static void operatorString(String name, Consumer<String> con, Consumer<String> con2) {
/*        con.accept(name);
        con2.accept(name);*/
        con.andThen(con2).accept(name);
/*        default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
        * */
    }

    //定義一個方法消費一個字符串
    private static void operatorString(String name, Consumer<String> con) {
        con.accept(name);
    }
}


/*
生餘後往
往後
2
---------------------
貞茂李
---------------------
生餘後往
往後
2
*/

public class ClientTcp {
    public static void main(String[] args) throws IOException {
        /*
    String[] strArray = {"李茂貞,25", "李淳風,27", "袁天罡,29"};
    字符串數組中有多條信息,請按照格式:"姓名:XX,年齡:XX"的格式將信息打印出來
    要求:
        把打印姓名的動作作爲第一個Consumer接口的Lambda實例
        把打印年齡的動作作爲第二個Consumer接口的Lambda實例
        將兩個Consumer接口按照順序組合到一起使用
 */
        String[] strArray = {"李茂貞,25", "李淳風,27", "袁天罡,29"};
        //匿名內部類的方式
/*        printInfo(strArray, new Consumer<String>() {
            @Override
            public void accept(String s) {
                String name = s.split(",")[0];
                System.out.print("姓名: " + name);
            }
        }, new Consumer<String>() {
            @Override
            public void accept(String s) {
                String age = s.split(",")[1];
                System.out.println(", 年齡:" + age);
            }
        });*/
        //lambda表達式的方式
/*        printInfo(strArray, (s) ->{
            String name = s.split(",")[0];
            System.out.print("姓名: " + name);
        }, (s)->{
            String age = s.split(",")[1];
            System.out.println(", 年齡: " + age);
        });*/
        //lambda表達式的省略模式
        printInfo(strArray, s -> System.out.print("姓名: " + s.split(",")[0]),
                s -> System.out.println(", 年齡: " + s.split(",")[1]));
    }

    //定義一個方法消費字符串數組
    private static void printInfo(String[] strArray, Consumer<String> con, Consumer<String> con2) {
        for (String str : strArray) {
            con.andThen(con2).accept(str);
        }
    }
}

/*
姓名: 李茂貞, 年齡: 25
姓名: 李淳風, 年齡: 27
姓名: 袁天罡, 年齡: 29
*/
  • 常用函數式接口之Predicate

Predicate接口通常用於判斷參數是否滿足指定的條件  常用方法

方法名

說明

boolean test(T t)

對給定的參數進行判斷(判斷邏輯由Lambda表達式實現),返回一個布爾值

default Predicate negate()

返回一個邏輯的否定,對應邏輯非

default Predicate and(Predicate other)

返回一個組合判斷,對應短路與

default Predicate or(Predicate other)

返回一個組合判斷,對應短路或

/*
    Predicate<T>:常用的四個方法
        boolean test​(T t):對給定的參數進行判斷(判斷邏輯由Lambda表達式實現),返回一個布爾值
        default Predicate<T> negate​():返回一個邏輯的否定,對應邏輯非
        Predicate<T>接口通常用於判斷參數是否滿足指定的條件
 */
public class Test {
    public static void main(String[] args) {
        //匿名內部類
        boolean result = checkLength("往後餘生", new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() > 5;
            }
        });
        System.out.println(result);
        //lambda表達式
        boolean checkResult = checkLength("餘生,請多指教", s -> s.length() > 5);
        System.out.println(checkResult);
    }

    public static boolean checkLength(String str, Predicate<String> per) {
        //return per.test(str);
        return per.negate().test(str);  //negate 邏輯非
/*        default Predicate<T> negate() {
            return (t) -> !test(t);
        }*/
    }
}
/*
    Predicate<T>:
        default Predicate<T> and​(Predicate other):返回一個組合判斷,對應短路與
        default Predicate<T> or​(Predicate other):返回一個組合判斷,對應短路或
 */
public class Test {
    public static void main(String[] args) {
        //lambda表達式
        boolean checkResult = checkLength("餘生,請多指教", s -> s.length() > 5 , s -> s.length() < 10);
        System.out.println(checkResult);

    }

    public static boolean checkLength(String str, Predicate<String> per1, Predicate<String> per2) {
/*        boolean re1 = per1.test(str);
        boolean re2 = per2.test(str);
        return re1 && re2;*/
        //等價於
        //return per1.and(per2).test(str);  //短路邏輯與
        /*        boolean re1 = per1.test(str);
        boolean re2 = per2.test(str);
        return re1 || re2;*/
        //等價於
        return per1.or(per2).test(str);  //短路邏輯或
    }
}

/*
    String[] strArray = {"李茂貞,25", "衛莊,27", "蓋聶,30", "李淳風,31", "袁天罡,33"};
    字符串數組中有多條信息,請通過Predicate接口的拼裝將符合要求的字符串篩選到集合ArrayList中,並遍歷ArrayList集合
    要求:同時滿足如下要求
        1:姓名長度大於2
        2:年齡小於31
    分析:
        1:有兩個判斷條件,所以需要使用兩個Predicate接口,對條件進行判斷
        2:必須同時滿足兩個條件,所以可以使用and方法連接兩個判斷條件
 */
public class Test {
    public static void main(String[] args) {
        String[] strArray = {"李茂貞,25", "衛莊,27", "蓋聶,30", "李淳風,31", "袁天罡,33"};
        //lambda表達式
        ArrayList strList = checkLength(strArray, s -> s.split(",")[0].length() > 2 ,
                s -> Integer.parseInt(s.split(",")[1]) < 31);
        System.out.println(strList);
    }

    public static ArrayList<String> checkLength(String[] strArray, Predicate<String> per1, Predicate<String> per2) {
        ArrayList<String> strList = new ArrayList<>();
        for (String str: strArray){
            if (per1.and(per2).test(str)){
                strList.add(str);
            }
        }
        return strList;
    }
}

/*
[李茂貞,25]
*/
  • 常用函數式接口之Function

/*
    Function<T,R>:常用的兩個方法
        R apply​(T t):將此函數應用於給定的參數
        default <V> Function andThen​(Function after):返回一個組合函數,首先將該函數應用於輸入,然後將after函數應用於結果
        Function<T,R>接口通常用於對參數進行處理,轉換(處理邏輯由Lambda表達式實現),然後返回一個新的值
 */
public class Test {
    public static void main(String[] args) {
        //匿名內部類
        convert("1252", new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                return Integer.parseInt(s);
            }
        });
        //lambda表達式
        convert("125220", s -> Integer.parseInt(s));
        //引用類方法
        convert("125220", Integer::parseInt);
        System.out.println("---------------------------");
        convert(100, s -> String.valueOf(s+566));
        System.out.println("---------------------------");
        convert("100", s -> Integer.parseInt(s), s -> String.valueOf(s+899));
    }

    //定義一個方法,把一個字符串轉換int類型,在控制檯輸出
    private static void convert(String str, Function<String, Integer> f) {
        Integer result = f.apply(str);
        System.out.println(result);
    }
    //定義一個方法,把一個int類型的數據加上一個整數之後,轉爲字符串在控制檯輸出
    private static void convert(int num, Function<Integer, String> f){
        String str = f.apply(num);
        System.out.println(str);
    }
    //定義一個方法,把一個字符串轉換int類型,把int類型的數據加上一個整數之後,轉爲字符串在控制檯輸出
    public static void convert(String str, Function<String, Integer> f1, Function<Integer, String> f2){
/*        int num = f1.apply(str);
        String result = f2.apply(num);
        System.out.println(result);*/
        String result = f1.andThen(f2).apply(str);
        System.out.println(result);
    }
}


/*
1252
125220
125220
---------------------------
666
---------------------------
999
*/

  • Stream流

/*
    需求:按照下面的要求完成集合的創建和遍歷
        1:創建一個集合,存儲多個字符串元素
        2:把集合中所有以"張"開頭的元素存儲到一個新的集合
        3:把"張"開頭的集合中的長度爲3的元素存儲到一個新的集合
        4:遍歷上一步得到的集合
 */
public class Test {
    public static void main(String[] args) {
        //創建一個集合,存儲多個字符串元素
        ArrayList<String> list = new ArrayList<>();

        list.add("林青霞");
        list.add("張曼玉");
        list.add("王祖賢");
        list.add("柳巖");
        list.add("張敏");
        list.add("張無忌");

/*        //把集合中所有以"張"開頭的元素存儲到一個新的集合
        ArrayList<String> zhangList = new ArrayList<>();
        for (String name : list) {
            if (name.startsWith("張")) {
                zhangList.add(name);
            }
        }

        //把"張"開頭的集合中的長度爲3的元素存儲到一個新的集合
        ArrayList<String> lenList = new ArrayList<String>();

        for (String s : zhangList) {
            if (s.length() == 3) {
                lenList.add(s);
            }
        }
        System.out.println(lenList);
        //Stream流來改進
        list.stream().filter((String s) -> s.startsWith("張")).filter((String s) -> s.length() == 3).forEach((String s) -> System.out.println(s));
        */
        //省略模式
        list.stream().filter(s -> s.startsWith("張")).filter(s -> s.length() == 3).forEach(System.out::println);
    }
}

/*
張曼玉
張無忌
*/

Stream流的思想

 

  •  Stream流的生成方式

/*
    Stream流的常見生成方式
        1:Collection體系的集合可以使用默認方法stream​()生成流
            default Stream<E> stream​()
        2:Map體系的集合間接的生成流
        3:數組可以通過Stream接口的靜態方法of​(T... values)生成流
 */
public class Test {
    public static void main(String[] args) {
        //1:Collection體系的集合可以使用默認方法stream​()生成流
        List<String> list = new ArrayList<String>();
        Stream<String> listStream = list.stream();

        Set<Integer> set = new HashSet<Integer>();
        Stream<Integer> setStream = set.stream();

        //2:Map體系的集合間接的生成流
        HashMap<String, Integer> hashMap = new HashMap<>();
        Stream<String> keyStream = hashMap.keySet().stream();
        Stream<Integer> valueStream = hashMap.values().stream();
        Stream<Map.Entry<String, Integer>> entryStream = hashMap.entrySet().stream();

        //3:數組可以通過Stream接口的靜態方法of​(T... values)生成流
        String[] strArray = {"aaa", "www", "ddd"};
        Stream<String> strArray1 = Stream.of(strArray);
        Stream<String> strArray2 = Stream.of("aaa", "www", "ddd");
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
    }
}
  • Stream流中間操作方法

概念中間操作的意思是,執行完此方法之後,Stream流依然可以繼續執行其他操作。

 常見方法

方法名

說明

Stream filter(Predicate predicate)

用於對流中的數據進行過濾

Stream limit(long maxSize)

返回此流中的元素組成的流,截取前指定參數個數的數據

Stream skip(long n)

跳過指定參數個數的數據,返回由該流的剩餘元素組成的流

static Stream concat(Stream a, Stream b)

合併ab兩個流爲一個流

Stream distinct()

返回由該流的不同元素(根據Object.equals(Object) )組

成的流

Stream sorted()

返回由此流的元素組成的流,根據自然順序排序

Stream sorted(Comparator comparator)

返回由該流的元素組成的流,根據提供的Comparator進行排序

Stream map(Function mapper)

返回由給定函數應用於此流的元素的結果組成的流

IntStream mapToInt(ToIntFunction mapper)

返回一個IntStream其中包含將給定函數應用於此流的元素的結果

/*
    Stream<T> filter​(Predicate predicate):用於對流中的數據進行過濾
    Predicate接口中的方法	boolean test​(T t):對給定的參數進行判斷,返回一個布爾值
 */
public class Test {
    public static void main(String[] args) {
        //創建一個集合,存儲多個字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("林青霞");
        list.add("張曼玉");
        list.add("王祖賢");
        list.add("柳巖");
        list.add("張敏");
        list.add("張無忌");

        //需求1:把list集合中以張開頭的元素在控制檯輸出
        //匿名內部類的方式
        list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.startsWith("張");
            }
        }).forEach(System.out::println);
        System.out.println("------------------------");
        //lambda表達式
        list.stream().filter(s -> s.startsWith("張")).forEach(System.out::println);
        System.out.println("------------------------");
        //需求2:把list集合中長度爲3的元素在控制檯輸出
        list.stream().filter(s -> s.length() == 3).forEach(System.out::println);
        System.out.println("------------------------");
        //需求3:把list集合中以張開頭的,長度爲3的元素在控制檯輸出
        list.stream().filter(s -> s.startsWith("張")).filter(s -> s.length() == 3).forEach(System.out::println);
    }
}

/*
張曼玉
張敏
張無忌
------------------------
張曼玉
張敏
張無忌
------------------------
林青霞
張曼玉
王祖賢
張無忌
------------------------
張曼玉
張無忌
*/

Stream limit(long maxSize)

返回此流中的元素組成的流,截取前指定參數個數的數據

Stream skip(long n)

跳過指定參數個數的數據,返回由該流的剩餘元素組成的流

/*
    Stream<T> limit​(long maxSize):返回此流中的元素組成的流,截取前指定參數個數的數據
    Stream<T> skip​(long n):跳過指定參數個數的數據,返回由該流的剩餘元素組成的流
 */
public class Test {
    public static void main(String[] args) {
        //創建一個集合,存儲多個字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("林青霞");
        list.add("張曼玉");
        list.add("王祖賢");
        list.add("柳巖");
        list.add("張敏");
        list.add("張無忌");

        //需求1:取前3個數據在控制檯輸出
        list.stream().limit(3).forEach(s -> System.out.println(s));
        System.out.println("-------------------");

        //需求2:跳過3個元素,把剩下的元素在控制檯輸出
        list.stream().skip(3).forEach(s -> System.out.println(s));
        System.out.println("-------------------");
        //需求3:跳過2個元素,把剩下的元素中前2個在控制檯輸出
        list.stream().skip(2).limit(2).forEach(s -> System.out.println(s));
    }
}

/*
林青霞
張曼玉
王祖賢
-------------------
柳巖
張敏
張無忌
-------------------
王祖賢
柳巖
*/

static Stream concat(Stream a, Stream b)

合併ab兩個流爲一個流

Stream distinct()

返回由該流的不同元素(根據Object.equals(Object) )組

成的流

/*
    static <T> Stream<T> concat​(Stream a, Stream b):合併a和b兩個流爲一個流
    Stream<T> distinct​():返回由該流的不同元素(根據Object.equals(Object) )組成的流
 */
public class Test {
    public static void main(String[] args) {
        //創建一個集合,存儲多個字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("林青霞");
        list.add("張曼玉");
        list.add("王祖賢");
        list.add("柳巖");
        list.add("張敏");
        list.add("張無忌");

        ///需求1:取前4個數據組成一個流
        Stream<String> stream1 = list.stream().limit(4);

        //需求2:跳過2個數據組成一個流
        Stream<String> stream2 = list.stream().skip(2);

        //需求3:合併需求1和需求2得到的流
        Stream<String> concatStream = Stream.concat(stream1, stream2);

        //需求4:合併需求1和需求2得到的流,並把結果在控制檯輸出,要求字符串元素不能重複
        concatStream.distinct().forEach(System.out::println);
    }
}

/*
林青霞
張曼玉
王祖賢
柳巖
張敏
張無忌
*/

Stream sorted()

返回由此流的元素組成的流,根據自然順序排序

Stream sorted(Comparator comparator)

返回由該流的元素組成的流,根據提供的Comparator進行排序

/*
    Stream<T> sorted​():返回由此流的元素組成的流,根據自然順序排序
    Stream<T> sorted​(Comparator comparator):返回由該流的元素組成的流,根據提供的Comparator進行排序
        Comparator接口中的方法	int compare​(T o1, T o2)
 */
public class Test {
    public static void main(String[] args) {
        //創建一個集合,存儲多個字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("linqingxia");
        list.add("zhangmanyu");
        list.add("wangzuxian");
        list.add("liuyan");
        list.add("zhangmin");
        list.add("zhangwuji");

        //需求1:按照自然順序把數據在控制檯輸出
        list.stream().sorted().forEach(s -> System.out.println(s));
        System.out.println("--------------------");
        //需求2:按照字符串長度從大到小,字母從小到達順序排序後把數據在控制檯輸出
        //匿名內部類的方式
        /*list.stream().sorted(new Comparator<String>() {
            @Override
            public int compare(String str1, String str2) {
                int num = str2.length() - str1.length();
                int result = num == 0? str1.compareTo(str2): num;
                return result;
            }
        }).forEach(s -> System.out.println(s));*/
        //lambda表達式
        list.stream().sorted((str1, str2)->{
            int num = str2.length() - str1.length();
            int result = num == 0? str1.compareTo(str2): num;
            return result;
        });
    }
}

/*
linqingxia
liuyan
wangzuxian
zhangmanyu
zhangmin
zhangwuji
--------------------
linqingxia
wangzuxian
zhangmanyu
zhangwuji
zhangmin
liuyan
*/

Stream map(Function mapper)

返回由給定函數應用於此流的元素的結果組成的流

IntStream mapToInt(ToIntFunction mapper)

返回一個IntStream其中包含將給定函數應用於此流的元素的結果

/*
    <R> Stream<R> map​(Function mapper):返回由給定函數應用於此流的元素的結果組成的流
        Function接口中的方法		R apply​(T t)
    IntStream mapToInt​(ToIntFunction mapper):返回一個IntStream其中包含將給定函數應用於此流的元素的結果
        IntStream:表示原始 int 流
        ToIntFunction接口中的方法	 int applyAsInt​(T value)
 */
public class Test {
    public static void main(String[] args) {
        //創建一個集合,存儲多個字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("10");
        list.add("20");
        list.add("30");
        list.add("40");
        list.add("50");

        //需求:將集合中的字符串數據轉換爲整數之後在控制檯輸出
/*        list.stream().map(new Function<String, Object>() {
            @Override
            public Object apply(String s) {
                return Integer.parseInt(s);
            }
        });*/
        //list.stream().map((s) -> Integer.parseInt(s)).forEach(s -> System.out.println(s));
        //list.stream().map(Integer::parseInt).forEach(System.out::println);
        //map、和mapToInt的區別在於map返回一個Stream流,mapInt返回一個IntStream
        Stream<Integer> stream = list.stream().map(Integer::parseInt);
        IntStream intStream = list.stream().mapToInt(Integer::parseInt);

        //int sum​() 返回此流中元素的總和
        int result = intStream.sum();
        System.out.println(result);
    }
}

/*
150
*/
  • Stream流終結操作方法

概念

終結操作的意思是,執行完此方法之後,Stream流將不能再執行其他操作。

 常見方法

方法名

說明

void forEach(Consumer action)

對此流的每個元素執行操作

long count()

返回此流中的元素數

public class Test {
    public static void main(String[] args) {
        //創建一個集合,存儲多個字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("10");
        list.add("20");
        list.add("30");
        list.add("40");
        list.add("50");

        //long count()	返回此流中的元素數
        long count = list.stream().count();
        System.out.println(count);
    }
}
/*
5
*/

/*
    現在有兩個ArrayList集合,分別存儲6名男演員名稱和6名女演員名稱,要求完成如下的操作:
        1:男演員只要名字爲3個字的前三人
        2:女演員只要姓林的,並且不要第一個
        3:把過濾後的男演員姓名和女演員姓名合併到一起
        4:把上一步操作後的元素作爲構造方法的參數創建演員對象,遍歷數據
            演員類Actor已經提供,裏面有一個成員變量,一個帶參構造方法,以及成員變量對應的get/set方法
*/
public class Test {
    public static void main(String[] args) {
        //創建集合
        ArrayList<String> manList = new ArrayList<String>();
        manList.add("周潤發");
        manList.add("成龍");
        manList.add("劉德華");
        manList.add("吳京");
        manList.add("周星馳");
        manList.add("李連杰");

        ArrayList<String> womanList = new ArrayList<String>();
        womanList.add("林心如");
        womanList.add("張曼玉");
        womanList.add("林青霞");
        womanList.add("柳巖");
        womanList.add("林志玲");
        womanList.add("王祖賢");

/*        //男演員只要名字爲3個字的前三人
        Stream<String> manStream = manList.stream().filter(s -> s.length() == 3);
        //女演員只要姓林的,並且不要第一個
        Stream<String> womanStream = womanList.stream().filter(s -> s.startsWith("林")).skip(1);
        //把過濾後的男演員姓名和女演員姓名合併到一起
        Stream<String> conStream = Stream.concat(manStream, womanStream);
        //把上一步操作後的元素作爲構造方法的參數創建演員對象,遍歷數據
        conStream.map(s -> new Actor(s)).forEach(s -> System.out.println(s.getName()));*/

        //省略模式
        Stream.concat(manList.stream().filter(s -> s.length() == 3), womanList.stream().filter(s -> s.startsWith("林")).skip(1))
                .map(Actor::new).forEach(s -> System.out.println(s.getName()));
    }
}
/*
周潤發
劉德華
周星馳
李連杰
林青霞
林志玲
*/
  • Stream流的收集操作

概念

對數據使用Stream流的方式操作完畢後,可以把流中的數據收集到集合中。

 常用方法

方法名

說明

R collect(Collector collector)

把結果收集到集合中

 工具類Collectors提供了具體的收集方式

方法名

說明

public static Collector toList()

把元素收集到List集合中

public static Collector toSet()

把元素收集到Set集合中

public static Collector toMap(Function keyMapper,Function valueMapper)

把元素收集到Map集合中

/*
    Stream流的收集方法
        R collect​(Collector collector)

    它是通過工具類Collectors提供了具體的收集方式
        public static <T> Collector toList​():把元素收集到List集合中
        public static <T> Collector toSet​():把元素收集到Set集合中
        public static Collector toMap​(Function keyMapper,Function valueMapper):把元素收集到Map集合中
 */
public class Test {
    public static void main(String[] args) {
        //創建List集合對象
        List<String> list = new ArrayList<String>();
        list.add("林青霞");
        list.add("張曼玉");
        list.add("王祖賢");
        list.add("柳巖");

        //需求1:得到名字爲3個字的流
        Stream<String> lenStream = list.stream().filter(s -> s.length() ==3);
        //需求2:把使用Stream流操作完畢的數據收集到List集合中並遍歷
        List<String> collectList = lenStream.collect(Collectors.toList());
        for(String name: collectList) System.out.println(name);
        System.out.println("----------------------");
        //創建Set集合對象
        Set<Integer> set = new HashSet<Integer>();
        set.add(10);
        set.add(20);
        set.add(30);
        set.add(33);
        set.add(35);

        //需求3:得到年齡大於25的流
        Stream<Integer> integerStream = set.stream().filter(s -> s > 25);
        //需求4:把使用Stream流操作完畢的數據收集到Set集合中並遍歷
        Set<Integer> ageSet = integerStream.collect(Collectors.toSet());
        for(Integer age: ageSet) System.out.println(age);
        System.out.println("----------------------");

        //定義一個字符串數組,每一個字符串數據由姓名數據和年齡數據組合而成
        String[] strArray = {"林青霞,30", "張曼玉,35", "王祖賢,33", "柳巖,25"};
        //需求5:得到字符串中年齡數據大於28的流
        Stream<String> stringStream = Stream.of(strArray).filter(s -> Integer.parseInt(s.split(",")[1]) > 28);
        //需求6:把使用Stream流操作完畢的數據收集到Map集合中並遍歷,字符串中的姓名作鍵,年齡作值
        Map<String, Integer> mapCollect = stringStream.collect(Collectors.toMap((s -> s.split(",")[0]), (s -> Integer.parseInt(s.split(",")[1]))));
        for(String key: mapCollect.keySet()){
            System.out.println("姓名: " + key + ", 年齡: " + mapCollect.get(key));
        }

    }
}
/*
林青霞
張曼玉
王祖賢
----------------------
33
35
30
----------------------
姓名: 林青霞, 年齡: 30
姓名: 王祖賢, 年齡: 33
姓名: 張曼玉, 年齡: 35
*/

 

 

 

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