1.lambda表达式匿名内部类优化
lambda语法 ()->{具体代码}
原本写法
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我是一个新线程");
}
}).start();
lambda写法
new Thread(()->{
System.out.println("这个是一个新线程");
}).start();
这样的代码是不是阅读性更高呢,但是匿名内部类这样写有一个前提就是只允许有一个方法才能这样直接引用
1.1理解Lambda的执行原理对比匿名内部类
看代码
这个接口是被@FunctionalInterface注解修饰的且只有一个抽象方法
这个IntBinaryOperator类下面只有applyAsInt方法,我们在main方法中调用Add就相当于通过add去调用接口的方法,然后我们用匿名内部类来调用
public static void main(String[] args) {
System.out.println(Add(new IntBinaryOperator() {
@Override
public int applyAsInt(int left, int right) {
return left+right;
}
}));
}
public static int Add(IntBinaryOperator exception){
int a =100;
int b =100;
return exception.applyAsInt(a,b);
}
Lambda方式方法(参数1,参数2)->{具体业务}
System.out.println(Add((left,right)->{
System.out.println("我是Lambda方式");
return left+right;
}));
1.2案例2自定义接口
@FunctionalInterface
public interface Hello {
// 获取一个四位数的字符串
String hello(String s);
}
public static String Wirte(Hello hello){
StringBuilder src = new StringBuilder();
String str = "1234567890QWERTYoprqejfnriojtrvb";
Random random = new Random();
for (int i = 0;i<4;i++){
String s = String.valueOf(str.charAt(random.nextInt(str.length())));
src.append(s);
}
return hello.hello(src.toString());
}
打印验证码
String str = Wirte((s)->{
return s;
});
System.out.println(str);
2、Stream流
Stream流是Java8新出的一中新特性,方便对数组集合进行更好的操作
2.1 准备工作
先导入实体类
Author类
/**
* @Author: 李佳芬
* @Description: TODO
* @DateTime: 2022/10/16 11:25
**/
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode//用于后期的去重使用
public class Author {
//id
private Long id;
//姓名
private String name;
//年龄
private Integer age;
//简介
private String intro;
//作品
private List<Book> books;
}
Book类
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode//用于后期的去重使用
public class Book {
//id
private Long id;
//书名
private String name;
//分类
private String category;
//评分
private Integer score;
//简介
private String intro;
}
编写静态方法生成数据更好的使用Stream流来操作数据
private static List<Author> getAuthors() {
//数据初始化
Author author = new Author(1L,"蒙多",33,"一个从菜刀中明悟哲理的祖安人",null);
Author author2 = new Author(2L,"亚拉索",15,"狂风也追逐不上他的思考速度",null);
Author author3 = new Author(3L,"易",14,"是这个世界在限制他的思维",null);
Author author4 = new Author(3L,"易",14,"是这个世界在限制他的思维",null);
//书籍列表
List<Book> books1 = new ArrayList<>();
List<Book> books2 = new ArrayList<>();
List<Book> books3 = new ArrayList<>();
books1.add(new Book(1L,"刀的两侧是光明与黑暗","哲学,爱情",88,"用一把刀划分了爱恨"));
books1.add(new Book(2L,"一个人不能死在同一把刀下","个人成长,爱情",99,"讲述如何从失败中明悟真理"));
books2.add(new Book(3L,"那风吹不到的地方","哲学",85,"带你用思维去领略世界的尽头"));
books2.add(new Book(3L,"那风吹不到的地方","哲学",85,"带你用思维去领略世界的尽头"));
books2.add(new Book(4L,"吹或不吹","爱情,个人传记",56,"一个哲学家的恋爱观注定很难把他所在的时代理解"));
books3.add(new Book(5L,"你的剑就是我的剑","爱情",56,"无法想象一个武者能对他的伴侣这么的宽容"));
books3.add(new Book(6L,"风与剑","个人传记",100,"两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢?"));
books3.add(new Book(6L,"风与剑","个人传记",100,"两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢?"));
author.setBooks(books1);
author2.setBooks(books2);
author3.setBooks(books3);
author4.setBooks(books3);
List<Author> authorList = new ArrayList<>(Arrays.asList(author,author2,author3,author4));
return authorList;
}
准备工作就好了
2.3 快速入门
需求
需求对所有作家进行去重 并过滤年龄大于18岁的作家
实现
// 需求对所有作家进行去重 并过滤年龄大于18岁的作家
List<Author> authors = getAuthors();
authors.stream()// 把集合转换成流
.distinct() // 这个方法是去重
.filter(author -> author.getAge() < 18).collect(Collectors.toList())
.forEach(author-> System.out.println(author.getName())); // 过滤年龄大于18的作家
2.4 使用Steam流操作集合
2.4.1 创建流
单例集合 set ,list 等
List<Author> authors = getAuthors();
Stream<Author> stream = authors.stream();
数组
Integer[] arr = {1,2,3,4,5};
Stream<Integer> stream = Arrays.stream(arr);
stream.distinct().forEach(System.out::println);
双列集合 map
Map<String,Integer> map = new HashMap<>();
map.put("张三",20);
map.put("李四",20);
map.put("王二",23);
Set<Map.Entry<String, Integer>> entrySet = map.entrySet(); //转换成set集合
entrySet.stream().distinct().filter(entry-> entry.getValue()!=23).forEach(entry -> System.out.println(entry.getKey()));
2.5 中间操作
2.5.1 filter
过滤方法具体看代码实现 需求打印作家姓名长度大于1且年龄大于19的作家
List<Author> authors = Utils.getAuthors();
authors.stream().distinct().filter(author->author.getName().length()>1)
.filter(author->author.getAge()>19)
.forEach(System.out::println);
这里filter就是过滤的用处把姓名长度和年龄不达标的都过滤了
2.5.2 map
类型转换 需求单独提取作家的姓名
List<Author> authors = Utils.getAuthors();
authors.stream().map(Author::getName) // 提取出来直接返回姓名
.forEach(System.out::println);
2.5.3 distinct
去重 需求打印作家的名字不能重复
List<Author> authors = Utils.getAuthors();
authors.stream().distinct()
.map(Author::getName)
.forEach(System.out::println);
2.5.4 sorted
对流中的元素进行排序
需求对流中的元素按照年龄进行降序排序,并且要求不能有重复的元素、
List<Author> authors = Utils.getAuthors();
authors.stream().distinct()
.sorted((o1,o2)-> o2.getAge()- o1.getAge())
.forEach(author -> System.out.println(author.getAge()));
2.5.5 limit
可以设置流的最大长度,超出的部分将被抛弃。
例如:对流中的元素按照年龄进行降序排序,并且要求不能有重复的元素,然后打印其中年龄最大的两个作家的姓名。
List<Author> authors = Utils.getAuthors();
authors.stream().distinct().sorted((o1,o2)-> o2.getAge()- o1.getAge())
.limit(2)
.forEach(author -> System.out.println(author.getName()+" "+author.getAge()));