stream与函数式接口


title: stream与函数式接口
date: 2019-07-24 14:03:02
categories:

  • java基础
    tags:

1. 思维导图

思维导图

2. Stream 与函数式接口

2.1. 获取流

  • 所有的 Collection 集合都可以通过 stream 默认方法获取流
  • Stream 接口的静态方法 of 可以获取数组对应的流
  • Map 不是集合类型,需要根据 key, value, entry 分别获取相应的流

2.2. 流的方法

2.2.1. forEach

  • void forEach(Consumer<? super T> action);

2.2.2. filter

  • Stream filter(Predicate<? super T> predicate);

2.2.3. map

将流中的元素映射到另一个流中,通常是用来转换成另一个类型

  • Stream map(Function<? super T, ? extends R> mapper);

2.2.4. count

  • long count();

2.2.5. limit

  • Stream limit(long maxSize);

2.2.6. skip

  • Stream skip(long n);

2.2.7. concat

  • static Stream concat(Stream<? extends T> a, Stream<? extends T> b)

2.3. collect 的使用

2.3.1. 转换为 list

  • collect.()

2.3.2. 转换为 map

传入 key, value 即可

  • public static <T,K,U> Collector<T,?,Map<K,U>> toMap(Function<? super T,? extends K> keyMapper,
    Function<? super T,? extends U> valueMapper)
  • 例如:Stream.concat(one.stream(), two.stream()).collect(Collectors.toMap(s -> s, s -> new Person(s)));

2.4. 流的方法练习

package javaBase.Stream;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author jhmarryme.cn
 * @date 2019/7/24 11:21
 */
public class StreamAndFunctionalInterface {


    /**
     * 测试流的各种方法结合常用函数式接口的使用
     * @param args
     */
    public static void main(String[] args) {
        ArrayList<String> one = new ArrayList<>();

        one.add("迪丽热巴");
        one.add("宋远桥");
        one.add("苏星河");
        one.add("石破天");
        one.add("石中玉");
        one.add("老子");
        one.add("庄子");
        one.add("洪七公");

        //第二支队伍
        ArrayList<String> two = new ArrayList<>();
        two.add("古力娜扎");
        two.add("张无忌");
        two.add("赵丽颖");
        two.add("张三丰");
        two.add("尼古拉斯赵四");
        two.add("张天爱");
        two.add("张二狗");



//        1. 第一个队伍只要名字为3个字的成员姓名;存储到一个新集合中。
        one.stream().filter(s -> s.length() == 3).collect(Collectors.toList()).forEach(s -> System.out.println(s));
        System.out.println("------------");

//        2. 第一个队伍筛选之后只要前3个人;存储到一个新集合中。
        one.stream().limit(3).collect(Collectors.toList()).forEach(s -> System.out.println(s));
        System.out.println("------------");

//        3. 第二个队伍只要姓张的成员姓名;存储到一个新集合中。
        two.stream().filter(s -> s.startsWith("张")).collect(Collectors.toList()).forEach(s -> System.out.println(s));
        System.out.println("------------");

//        4. 第二个队伍筛选之后不要前2个人;存储到一个新集合中。
        two.stream().skip(2).collect(Collectors.toList()).forEach(s -> System.out.println(s));
        System.out.println("------------");

//        5. 将两个队伍合并为一个队伍;存储到一个新集合中。
        Stream<String> stream = Stream.concat(one.stream(), two.stream());
//        stream.collect(Collectors.toList()).forEach(s -> System.out.println(s));
        System.out.println("------------");

//        6. 根据姓名创建`Person`对象;存储到一个新集合中。
//        7. 打印整个队伍的Person对象信息。
        stream.map(s -> {
            return new Person(s);
        }).collect(Collectors.toList()).forEach(person -> System.out.println(person.toString()));


        //8. 补充, 将list映射为map
        final Map<String, Person> map = Stream.concat(one.stream(), two.stream()).collect(Collectors.toMap(s -> s, s -> new Person(s)));
        final Set<Map.Entry<String, Person>> entries = map.entrySet();
        for (Map.Entry<String, Person> entry : entries) {
            System.out.print(entry.getKey());
            System.out.println(" : " + entry.getValue().toString());
        }


        //将int数组转换为list
        int[] arr = {1,2,3,2,2,2,5,4,2};


        //boxed装箱
        final List<Integer> collect = Arrays.stream(arr).boxed().collect(Collectors.toList());
        final Iterator<Integer> iterator = collect.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next() +  " ");
        }

        //将list转换为int[], 因为int不是包装类型, 需要做转换
        final int[] array = collect.stream().mapToInt(Integer::intValue).toArray();
        for (int i : array) {
            System.out.print(i + " ");
        }

    }


}

2.5. 函数式接口

有且仅有一个抽象方法的接口

2.5.1. Supplier

生产一个数据

  • T get()

2.5.2. Consumer

是消费一个数据

  • void accept(T t)
  • 默认方法:andThen

2.5.3. Predicate

对某种类型的数据进行判断

  • boolean test(T t)
  • 默认方法:and or negate

2.5.4. Function<T,R>

根据一个类型的数据得到另一个类型的数据

  • R apply(T t)
  • 默认方法:andThen

2.6. 函数式接口方法练习

2.6.1. 比较器

package javaBase.functionalInterface.functionalInterfaceDemo;

import java.util.Arrays;

/**
 * 通过lambda表达式 作为比较器
 * @author jhmarryme.cn
 * @date 2019/7/22 9:43
 */
public class LambdaForComparatorDemo {

    public static void main(String[] args) {
        String[] array = { "abc", "ab", "abcd" };
        System.out.println(Arrays.toString(array));
        Arrays.sort(array, (a, b) -> {
        return a.length() - b.length();
    });
        System.out.println(Arrays.toString(array));

    }
}

2.6.2. consumer

package javaBase.functionalInterface.functionalInterfaceDemo;

import java.util.function.Consumer;

/**
 * 测试Consumer接口
 * 消费一个指定泛型的数据, 无返回值
 * 可通过andThen组合操作
 * @author jhmarryme.cn
 * @date 2019/7/22 11:21
 */
public class LambdaForConsumerDemo {

    public static void consumerString(String[] info, Consumer<String> con1, Consumer<String> con2, Consumer<String> con3){

        for (String s : info) {
            con1.andThen(con2).andThen(con3).accept(s);
        }

    }

    public static void main(String[] args) {

        String[] array = { "迪丽热巴,女, 14", "古力娜扎,女, 12", "马尔扎哈,男, 121" };

        consumerString(array,
                s -> System.out.print("姓名: " + s.split(",")[0]),
                s -> System.out.print("性别: " + s.split(",")[1]),
                s -> System.out.println("年龄: " + s.split(",")[2])
                );
    }
}

2.6.3. supplier

package javaBase.functionalInterface.functionalInterfaceDemo;

import java.util.function.Supplier;

/**
 * 测试Supplier接口
 * 包含一个无参的方法, 用来获取一个泛型参数指定类型的对象数据
 * @author jhmarryme.cn
 * @date 2019/7/22 9:52
 */
public class LambdaForSupplierDemo {

    public static void main(String[] args) {
        /*String msgA = "Hello";
        String msgB = "World";

        System.out.println(getString(() -> msgA + msgB));*/

        int arr[] = {2,3,4,52,333,23};

        System.out.println(getMax(() -> {

            int max = arr[0];
            for (int i : arr) {
                max = i > max ? i : max;
            }
            return max;
        }));
    }


    public static int getMax(Supplier<Integer> integerSupplier){
        return integerSupplier.get();
    }



    public static String getString(Supplier<String> stringSupplier){
        return stringSupplier.get();
    }



}

2.6.4. function

package javaBase.functionalInterface.functionalInterfaceDemo;

import java.util.function.Function;

/**
 * 通过函数式结构练习function接口
 * 根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件
 * @author jhmarryme.cn
 * @date 2019/7/22 13:15
 */
public class LambdaForFunctionDemo {


    /**
     * 根据接口的泛型
     * apply方法中参数类型为String, 返回Integer
     * @param integerFunction
     */
    public static void method(Function<String, Integer> integerFunction){

        final Integer apply = integerFunction.apply("5");
        System.out.println(apply + 20);
    }


    /**
     * 在前一个function的基础上再进行处理
     * 第二个function的第一个泛型必须为前一个function的后一个泛型
     * 相当于前一个的结果为Integer, 后一个就必须用Integer接收
     * @param f1
     * @param f2
     */
    public static void methood(Function<String, Integer> f1, Function<Integer, Integer> f2){

        final Integer apply = f1.andThen(f2).apply("1");
        System.out.println(apply);
    }

    /**
     * 截取数字部分, 得到的结果加上100返回
     * @param str
     * @param f1
     * @param f2
     * @return
     */
    public static Integer getAgeNum(String str, Function<String, Integer> f1, Function<Integer, Integer> f2){
        return f1.andThen(f2).apply(str);
    }


    public static void main(String[] args) {
//        method((s) -> Integer.parseInt(s));

//        methood(s -> Integer.parseInt(s)+1, i -> i = ((int)Math.pow(i, 10)));
        String str = "赵丽颖,20";
        final Integer ageNum = getAgeNum(str,
                s -> Integer.parseInt(s.split(",")[1]),
                i -> i = i + 100
        );

        System.out.println(ageNum);
    }
}

2.6.5. predicate

package javaBase.functionalInterface.functionalInterfaceDemo;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

/**
 * 通过函数式接口练习predicate相关的方法
 * 对泛型指定数据类型进行判断, 得到一个布尔值.
 * 包含与或非and, or, negate
 * @author jhmarryme.cn
 * @date 2019/7/22 12:54
 */
public class LambdaForPredicateDemo {

    public static Boolean method( Predicate<String> stringPredicate){
        return stringPredicate.test("helloWorld");
    }

    public static void method(Predicate<String> p1, Predicate<String> p2){

        final boolean helloWorld = p1.or(p2).test("HelloWorld");
        System.out.println(helloWorld);

    }



    public static ArrayList<String> filterString(String[] arr, Predicate<String> stringPredicate){

        final ArrayList<String> list = new ArrayList<>();

        for (String s : arr) {
            if (stringPredicate.test(s)) {
                list.add(s);
            }
        }
        return list;
    }



    public static void main(String[] args) {

        /*System.out.println(method(s -> {
            return s.length() > 5;
        }));
*/

//        method(s -> s.contains("el"), s -> s.length() > 10);



        /**
         * 筛选条件:
         * 必须为女生;
         * 姓名为4个字。
         */
        String[] array = { "迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男", "赵丽颖,女" };
        final ArrayList<String> arrayList = filterString(array, s -> {

            return s.split(",")[1].equals("女") && s.split(",")[0].length() == 4;

        });
        for (String s : arrayList) {
            System.out.println(s);
        }


    }
}

2.6.6. lambda延迟加载

package javaBase.functionalInterface.DelayForLambda;

import static javaBase.functionalInterface.DelayForLambda.MessageBuilder.MAX_NUM;

/**
 * 测试lambda表达式的延迟执行
 * 优化性能, 在不符合条件时, 不会执行lambda的内容
 * @author jhmarryme.cn
 * @date 2019/7/22 9:32
 */
public class DelayForLambdaDemo {

    public static void log(int level, MessageBuilder builder){
        if (level == 1) {
            System.out.println(builder.messageBuilder());
        }
    }


    public static void main(String[] args) {
        String msgA = "Hello";
        String msgB = "World";
        String msgC = "Java";
        //这里的拼接字符串 在条件不成立时不会执行
        log(1, () -> msgA + msgB + msgC );
    }
}


package javaBase.functionalInterface.DelayForLambda;

/**
 * @author jhmarryme.cn
 * @date 2019/7/22 9:33
 */

@FunctionalInterface
public interface MessageBuilder {

    int MAX_NUM = 97;
    /**
     * 测试lambda延迟加载
     * @return
     */
    String messageBuilder();
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值