Lambda的使用与流式编程

JDK新特性

函数式接口

1.说说JDK中函数式接口家族?

Function入参-1 返回值-1

​ – BiFunction入参-2返回值-1(两个入参,两个返回值B->Binary二进制)

在这里插入图片描述

Consumer 消费者入参-1

​ – BiConsumer

在这里插入图片描述

Supplier 提供者返回值-1

在这里插入图片描述

Predicate断言入参-1 返回值-布尔类型

在这里插入图片描述

双shift进行查找

在这里插入图片描述

2.Lambda表达式

使用它的原因:1.不想再单独封装一个新的实现类 2.想获取调用方定义的一些变量,而不想通过传参的方式使用

缺点:重用受限制

转换为Lambda表达式的流程:

1、去掉类型声明和()
2、去掉方法修饰符、返回类型、方法名
3、在参数列表和方法体的左括号之间标记一个"->"
基于上述的简化,还有如下更简洁的写法:
1、参数列表中每一个参数的类型声明都可以去掉
2、如果方法逻辑中只有一行代码,可以把这个方法体的“0”、”; "、“return”

比如:

  private static Comparator<User> c = new Comparator<User>() {
        @Override
        public int compare(User o1, User o2) {
            return o1.getName().compareTo(o2.getName());
        }
    };
Lamda后:
private static Comparator<User> c = (o1,  o2)->o1.getName().compareTo(o2.getName());

3.Lambda的方法引用

静态方法使用类名::方法名
非静态方法使用this::方法名或实例名::方法名

  原来:show(users,user-> System.out.println(user));
  变换后(输出语句是System.out类的)show(users, System.out::println);
调用的方法:
     public static void show(List<User> list, ShowInfo showInfo) {
        for (User u : list) {
            showInfo.showUser(u);
        }
    }
lamda实现的接口:
public interface ShowInfo {

    void showUser(User user);

}

完成此题:

请声明一个Consumer类型变量,具体的逻辑如下:
1.接收一个集合作为输入参数,然后对集合中的元素进行排序,然后再输出它们的信息.2.使用这个Consumer变量,实例化一个集合,传递给它,让它执行

package com.think.dashazi;

import com.think.lv1.utils.RandomUtils;//这个工具类代码也在下面

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;

public class Anonymity {

    public static void main(String[] args) {
        testConsumerAndSupplier(c0,s0);
    }
    //Supplier接口的Lambda实现
    public  static  final Supplier<List<User>> s0 = ()->{
        List<User> list = new ArrayList<>();
        for (int i = 0; i <5 ; i++) {
            list.add(new User(RandomUtils.randomString(),RandomUtils.randomNumber(100)));
        }
        return list;
    };

    //Consumer接口的Lambda实现
     public  static  final Consumer<List<User>> c0 = (users)->{
      // Collections.sort(users, (o1,o2)-> o1.getName().compareTo(o2.getName()));
         Collections.sort(users, Comparator.comparing(User::getName));
         System.out.println(users);

      };
     public  static  void testConsumerAndSupplier(Consumer<List<User>> c,Supplier<List<User>> s){
         List<User> list = s.get();//获取
         c.accept(list);//把list拿去处理
     }
}

package com.think.dashazi;

import java.util.Comparator;

public class User  {
    private String name;
    private int age;

    public User() {
    }

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

    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;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }


    // @Override
    // public int compare(User o1, User o2) {
    //     return o1.getName().compareTo(o2.getName());//正序 1,2,3从小到大
    // }
}

RandomUtils工具类

package com.think.lv1.utils;

import java.util.Random;
import java.util.concurrent.TimeUnit;

public class RandomUtils {

    // Utility 工具

    // CTRL + SHIFT + U 批量转换大小写
    // static 修饰的内容,是不依赖于这个类的任何实例的,当这个类一旦在运行期间加载进来,它就已经存在,有且只有一份,大家共享的
    // static修饰的方法只能访问static修饰的变量
    private final static String data = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; // 字典数据
    private static final Random ran = new Random(); // 对于引用类型,只要它自己的地址不发生改变,也可以修饰为final的

    // private static final String[] genders = new String[]{"male, female"};
    private static final String[] genders = {"male", "female"}; // 利用了编译器的优化机制(语法糖)进行简化,和上面这一行等效

    public static void longSleep(int min, int max) {
        int time = randomNumber(min, max);
        try {
            // Thread.sleep(time);
            TimeUnit.MILLISECONDS.sleep(time); // 代码易读,语义更清晰
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public static void longSleep(int sec) {
        try {
            // Thread.sleep(time);
            TimeUnit.MILLISECONDS.sleep(sec); // 代码易读,语义更清晰
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * <p>生成步骤</p>
     * <ul>
     *     <li>对字典字符串拆分,得到一个字符数组</li>
     *     <li>产生某一个合适范围的索引值</li>
     *     <li>把字符数组变换成一个完整的字符串</li>
     * </ul>
     *
     * @param len 表示要生成的字符串长度
     * @return 返回一个随机内容的字符串
     */
    public static String randomString(int len) {
        // String[] split = data.split("");
        char[] chars = data.toCharArray(); // 'A'
        // 循环从split数组中随机获取一个字符,然后组装成一个完整字符串
        // 创建一个临时存放零散字符的数组
        char[] temp = new char[len]; // 用来构造一个完整的字符串的
        for (int j = 0; j < len; j++) {
            char c = chars[ran.nextInt(data.length())]; // [0, data.length())
            temp[j] = c;
        }
        return new String(temp); // 不使用字符串的拼串是因为会产生大量的内存零时垃圾
    }

    public static String randomString() {
        return randomString(5); // 重用上面的逻辑
    }

    /**
     * 产生从from到to之间的某一个数字,包左,不包右
     *
     * @param min 最小值
     * @param max 最大值
     */
    public static int randomNumber(int min, int max) { // 3 - 10
        if (max < min) {
            System.out.printf("%d 不能 比 %d 小\r\n", max, min);
        }
        return ran.nextInt(max - min) + min;
    }

    /**
     * 产生从 1 到to之间的某一个数字,包左,不包右
     *
     * @param max 最大值
     */
    public static int randomNumber(int max) {
        return randomNumber(1, max);
    }

    public static String randomGender() {
        // return ran.nextBoolean() ? "male" : "female";
        int index = ran.nextInt(2); // 0 1
        return genders[index];
        // return genders[ran.nextInt(2)];
    }
}

流式编程

简单入门:

 		// 整数流的创建
        IntStream stream = Arrays.stream(arr);
        stream.forEach(System.out::println);

        System.out.println("------------------------------------------");
        // 经过上述的逻辑,指针已经指向了数据流的末尾了
        stream = Arrays.stream(arr);
        // 像是把整个数组,变成了一股由各个元素组成的水流
        stream
                .filter((item) -> item % 2 == 0) // 使用断言进行过滤
                // .limit(5) // 限定最后结果为5个
                .forEach(System.out::println);
基本下面都是一些方法的调用
package com.think.lv2.stream;

import com.think.lv1.utils.RandomUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

public class ListDemo {
    public static void main(String[] args) {
        // Function<Integer, List<User>> fn = (size) -> {
        //     List<User> users = new ArrayList<>();
        //     for (int i = 0; i < size; i++) {
        //         users.add(new User(RandomUtils.randomString(), RandomUtils.randomNumber(100)));
        //     }
        //     return users;
        // };
        //
        // List<User> users = fn.apply(20);
        //
        // // users.stream()
        // //         // 在此处开了一个小窗口,让你可以在不修改数据的情况下去窥探里面的每一个元素的内容
        // //         // 一般用于开发人员调试逻辑
        // //         .peek(u -> System.out.println(u.getAge()))
        // //         .filter(u -> u.getAge() > 18)
        // //         .forEach(System.out::println);
        //
        // // users.stream()
        // //         // .map( user -> user.getName() )
        // //         // .map(User::getName)
        // //         // 一旦使用map进行了类型转换,那么在这个流的后面,就只剩下被转换的内容了
        // //         // .mapToInt(User::getAge)
        // //         .sorted(Comparator.comparing(User::getName))
        // //         .forEach(System.out::println);
        //
        // // 重新收集符合条件的一个新集合
        // List<User> userList = users.stream()
        //         .filter(user -> user.getAge() >= 18)
        //         .sorted(Comparator.comparing(User::getName))
        //         .collect(Collectors.toList());
        //
        // List<String> nameList = users.stream()
        //         .map(User::getName)
        //         .collect(Collectors.toList());
        //
        // // long count = users.stream().count();
        //
        // // 该流中只要有一个匹配断言,就为true
        // boolean flag = users.stream().anyMatch(user -> user.getAge() >= 18);
        //
        // users.stream().findFirst();// 找到第一个
        // users.stream().findAny(); // 找到任何一个
        //
        // Optional<User> opt = users.stream().max(Comparator.comparing(User::getAge));
        //
        // if(opt.isPresent()) { // 找到了符合条件的
        //     User user = opt.get(); // 去获取它
        //     System.out.println(user);
        // }

        testGroup();
    }

    private static void testGroup() {
        Function<Integer, List<User>> fn = (size) -> {
            List<User> users = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                users.add(new User(RandomUtils.randomString(), RandomUtils.randomNumber(100), RandomUtils.randomNumber(4)));
            }
            return users;
        };

        List<User> users = fn.apply(30);

        // 根据班级来分组,要求得到3个独立的集合或者数组

        // Map<Boolean, List<User>> collect = users.stream().collect(Collectors.partitioningBy(user -> user.getAge() >= 18));//只能分成两个组,一个是满足要求的,一个是不满足要求的
        // Set<Map.Entry<Boolean, List<User>>> entries = collect.entrySet();
        //
        // for (Map.Entry<Boolean, List<User>> entry : entries) {
        //     System.out.println(entry.getKey() + ":" + entry.getValue());
        // }

        Map<Integer, List<User>> collect = users.stream()
                .collect(Collectors.groupingBy(User::getClassNo));

        // 根据2个甚至更多个字段来分组(这些字段的值都一样,认为是一组的)
        // users.stream().collect(Collectors.groupingBy( user -> user.getA() + user.getB()));

        Set<Map.Entry<Integer, List<User>>> entries = collect.entrySet();

        for (Map.Entry<Integer, List<User>> entry : entries) {
            System.out.println(entry.getKey() + ":" + entry.getValue());
        }
    }
}

完成下题:

根据2个班级和年龄甚至更多个字段来分组(提示:这些字段的值都一样,认为是一组的,使用

收集器collect(Collectors.groupingBy(user->user.getAge()>=18)))

 users.stream().collect(Collectors.groupingBy( user -> user.getClassNo() + user.getAge()));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值