目录
Lambda表达式
1、概念
2、使用规则
3、代码示例
Stream流
1、概念
2、使用
3、代码示例
方法引用
1、概念
2、适用情况
3、代码示例
总结
Lambda表达式为一种函数式编程方式,是jdk8中引入的新特性之一,是针对函数式接口的匿名内部类的实现。它提供了一种更简洁、直观的方式来实现函数式编程,使得代码更加易读和易写。这里的易读大家可能不是很赞同,其实当你用习惯了后,确实会觉得这种方式很爽,简单粗暴,一开始用起来可能不是很适应。下面的例子可以带大家感受一下为啥说简单粗暴!需要注意的是,Lambda只针对函数式接口的匿名内部类!
函数式接口:是指有且仅有一个抽象方法的接口,被@FunctionalInterface注解标记的接口也是函数式接口。
这里我个人觉得看代码比较直观,就直接上代码了。
@Test
public void test1(){
Map map = new HashMap<>();
map.put("ahaaa",11);
map.put("cpx",23);
map.put("lch",4245);
map.put("chamu",35);
Set> entries = map.entrySet();
// 原本 (这里的stream()等都是Stream流的应用,大家可以先忽略,关注排序sorted()方法里面的变化即可
// entries.stream().sorted(new Comparator>() {
// @Override
// public int compare(Map.Entry o1, Map.Entry o2) {
// return o2.getValue() - o1.getValue();
// }
// }).forEach(e -> System.out.println(e.getKey()+"----"+e.getValue()));
// lambda改写后(省略了o1,o2的参数类型、省略了{ }、省略了return和 ; 号)
entries.stream().sorted((o1, o2) -> o1.getValue() - o2.getValue())
.forEach(e -> System.out.println(e.getKey()+"----"+e.getValue()));
}
Stream流也是jdk8中引入的新特性之一,它主要用于处理集合数据,把集合转化成流来操作,把复杂的集合操作以简洁的方式表达出来,具有更高的可读性和可维护性。主要用来结合Lambda表达式语法编程。
首先是获取集合的Stream流,然后再进行过滤、排序、去重等等操作。其中数组获取流的方式与集合不同,具体看下列代码演示。
注:以上为一些常用的方法,还有其他方法具体可以查看相关api。
数组
@Test
public void test3(){
// 数组转stream流
String[] names = {"ahaaaa","cpx","lch","chamu"};
// 获取流方式1
// Stream namesStream = Stream.of(names);
// 获取流方式2
Stream stream = Arrays.stream(names).;
// 调用filter()进行过滤,判断集合中的对象e是否包涵“p”,若不包含过滤,然后调用forEach()进行遍历
stream.filter(e -> e.contains("p")).forEach(e -> System.out.println(e));
}
集合
@Test
public void test1(){
// list转stream流
List list = new ArrayList<>();
list.add("ahaaaa");
list.add("banana");
list.add("apple");
list.add("grapes");
list.add("watermelon");
// 调用filter()进行过滤,判断集合中的对象e是否包涵“b”,若不包含过滤,然后调用forEach()进行遍历
list.stream().filter(e -> e.contains("b")).forEach(e -> System.out.println(e));
// 调用count()获取集合格个数
System.out.println(list.stream().count());
}
方法引用是用于简化Lambda表达式的定义,它可以直接引用已有代码中的方法,作为Lambda表达式的替代形式,从而让代码更简洁、更易读。
这里结合下面三个代码示例理解比较简单
第一种适用情况
@Test
public void test1(){
List objects = new ArrayList<>();
Cat hei = new Cat("小黑", 11);
Cat bai = new Cat("小白", 23);
Cat lan = new Cat("小蓝", 45);
Cat hong = new Cat("小红", 64);
objects.add(hei);
objects.add(bai);
objects.add(lan);
objects.add(hong);
// 原本 第一步
// objects.stream().sorted(new Comparator() {
// @Override
// public int compare(Cat o1, Cat o2) {
// return o1.getAge()-o2.getAge();
// }
// }).forEach(e -> System.out.println(e.toString()));
// 改写成lambda 第二步
// objects.stream().sorted((o1, o2) -> o1.getAge()-o2.getAge())
// .forEach(e -> System.out.println(e.toString()));
// 改写成写好排序的CopareByAgeAsc()静态方法 第三步
// objects.stream().sorted((o1, o2) -> CompareByAge.CopareByAgeAsc(o1, o2))
// .forEach(e -> System.out.println(e.toString()));
// 改写成静态方法引用 第四步
// objects.stream().sorted(CompareByAge::CopareByAgeAsc)
// .forEach(e -> System.out.println(e.toString()));
}
第二种适用情况
@Test
public void test1(){
List objects = new ArrayList<>();
Cat hei = new Cat("小黑", 11);
Cat bai = new Cat("小白", 23);
Cat lan = new Cat("小蓝", 45);
Cat hong = new Cat("小红", 64);
objects.add(hei);
objects.add(bai);
objects.add(lan);
objects.add(hong);
// 原本
// objects.stream().sorted(new Comparator() {
// @Override
// public int compare(Cat o1, Cat o2) {
// return o1.getAge()-o2.getAge();
// }
// }).forEach(e -> System.out.println(e.toString()));
// 改写成lambda
// objects.stream().sorted((o1, o2) -> o1.getAge()-o2.getAge())
// .forEach(e -> System.out.println(e.toString()));
// 改写成调用实例方法引用
CompareByAge compareByAge = new CompareByAge();
// objects.stream().sorted((o1, o2) -> compareByAge.CopareByAgeDesc(o1, o2))
// .forEach(e -> System.out.println(e.toString()));
// 改写成实例方法引用
objects.stream().sorted(compareByAge::CopareByAgeDesc)
.forEach(e -> System.out.println(e.toString()));
}
第三种适用情况
@Test
public void test2(){
String[] strings = new String[]{"banana","ahaaaa","fix","available"};
// 原本
// Arrays.sort(strings, new Comparator() {
// @Override
// public int compare(String o1, String o2) {
// return o1.compareTo(o2);
// }
// });
// 改写成lambda
// Arrays.sort(strings, (o1, o2) -> o1.compareTo(o2));
// 改写成特定类型方法引用
Arrays.sort(strings, String::compareTo);
for (String string : strings) {
System.out.println(string);
}
}
总的来说,Lambda表达式、Stream流和方法引用这些新特性都致力于简化代码,提高代码的可读性和可维护性。它们让我们能够以更加直观的方式处理和操作数据,减少了冗余的代码和中间变量的使用,使得代码更简洁、更易理解和调试。同时,它们还提供了更高效的数据处理方式,能够更好地应对大数据量和并行处理的场景。只有熟练使用后,就会非常顺手,也会觉得非常的香。举个我遇到的场景,要for遍历一个集合,然后又要根据集合中的字段做排序,去重等等操作,需要10+行的代码,使用这些新特性后,一行代码就搞定了,而且可读性也非常的高,一眼就能看出过滤的条件,去重等逻辑代码。
上述示例代码我都放在了gitee中,需要的伙伴可以自己拿。