Lambda表达式的使用方法积累

  • A+
所属分类:Java

Lambda表达式的优缺点

优点:
  1. 简洁
  2. 易并行计算,特别适合便利结果,循环计算数值或者赋值的时候很方便
缺点:
  1. 若不用并行运算,很多时候计算方式速度没有传统的For循环快。
  2. 不容易使用Debug模式调试
  3. 在Lamdba语句中直接强制转换不方便
  4. 不可以再foreach中修改外面的值

Lambda表达式基本语法

(parameters) -> expression 或 (parameters) -> { statements; }

  • (parameters)这个参数名字可以自定义,但是一般要做到见名知意
  • -> Lambda表达式的符号
  • (parameters) -> expression 或 (parameters)->{方法体}

举个栗子:

public class LambdaDemo {

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");
        //使用list的forEach方法,s表示最终循环结果的变量。使用s->{方法体}
        list.forEach((s -> {
            System.out.println(s);
            //更多业务逻辑.....
        }));
    }
}

Lambda表达式的常用方法

1. 替代匿名内部类

lambda表达式用得最多的场合就是替代匿名内部类,而实现Runnable接口是匿名内部类的经典例子。lambda表达式的功能相当强大,用()->就可以代替整个匿名内部类!

普通表达式的例子:

new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("This is General expression");
            }
        }).start();

Lambda表达式的例子:

new Thread(() -> System.out.println("This is Lambda expression")).start();
2. Lambda表达式迭代集合

lambda表达式还可以很方便的进行集合的迭代,像平时常用的List、Map等容器都有很友好的支持。

普通表达式迭代例子:

List<String> list = Arrays.asList("A", "B", "C");
        for (String str : list) {
            System.out.println(str);
        }

Lambda表达式迭代例子:

list.forEach(x -> System.out.println(x)); //方式一
list.forEach(System.out::println); //方式二
3. Lambda表达式实现map
List<String> list = Arrays.asList("A", "B", "C");
list.stream().map(x -> x + "123").forEach(x -> System.out.println(x));
  • stream() 返回list集合流对象的引用
  • map() 返回一个流,包括将给定函数应用到该流元素的结果,也就是将一个对象变为另一个对象。
  • forEach 循环最终变化的对象
4、Lambda表达式实现map与reduce
  List<Integer> numList = Arrays.asList(3, 5, 7);
  Integer result = numList.stream().map(x -> x + x * 5).reduce((sum, x) -> sum + x).get();
  System.out.println(result);
  • stream() 返回list集合流对象的引用
  • map() 返回一个流,包括将给定函数应用到该流元素的结果,也就是将一个对象变为另一个对象。 这里的操作是将数组中的数值加上数组乘以3,最终得出另一个集合。{18,30,42}
  • reduce() 对结果进行运算,这里的操作是将集合中的值进行求和。
5、Lambda表达式进行filter过滤操作

filter也是我们经常使用的一个操作。在操作集合的时候,经常需要从原始的集合中过滤掉一部分元素。

 List<String> list = Arrays.asList("A", "B", "C");
 list.stream().filter(x -> x != "A").collect(Collectors.toList()).forEach(v -> System.out.println(v));
6、Lambda表达式使用forEach进行Map、List集合遍历

Map遍历

普通Map遍历方式

Map<String, Integer> items = new HashMap<>();
        items.put("A", 10);
        items.put("B", 20);
        items.put("C", 30);
        items.put("D", 40);
        items.put("E", 50);
        items.put("F", 60);
        for (Map.Entry<String, Integer> entry : items.entrySet()) {
            System.out.println("Item : " + entry.getKey() + " Count : " + entry.getValue());
        }

使用Lamdba表达式进行Map遍历

 Map<String, Integer> items = new HashMap<>();
        items.put("A", 10);
        items.put("B", 20);
        items.put("C", 30);
        items.put("D", 40);
        items.put("E", 50);
        items.put("F", 60);
        items.forEach((k,v)->System.out.println("Item : " + k + " Count : " + v));
        items.forEach((k,v)->{
            System.out.println("Item : " + k + " Count : " + v);
            if("E".equals(k)){
                System.out.println("Hello E");
            }
        });

List遍历

普通List遍历方式

 List<String> items = new ArrayList<>();
            items.add("A");
            items.add("B");
            items.add("C");
            items.add("D");
            items.add("E");

            for(String item : items){
                System.out.println(item);
            }

使用Lamdba表达式进行List遍历

 List<String> items = new ArrayList<>();
        items.add("A");
        items.add("B");
        items.add("C");
        items.add("D");
        items.add("E");
        //输出:A,B,C,D,E
        items.forEach(item->System.out.println(item));
        //输出 : C
        items.forEach(item->{
            if("C".equals(item)){
                System.out.println(item);
            }
        });

特别强调:数组不可以直接再forEach中使用Lambda表达式

PartnerType[] values = PartnerType.values();
//提示Cannot resolve method 'forEach(<method reference>)
values.forEach(System.out::println);//错误使用

如果想要使用forEach函数,需要将数组转换为stream或者list再进行遍历,如下:

PartnerType[] values = PartnerType.values();
Arrays.stream(values).forEach(System.out::println);//转成流
Arrays.asList(values).forEach(System.out::println);//转成list

Lambda操作积累

编写线程
Runnable runnable = () -> {
System.out.println("Lambda 创建线程");
};
Thread thread = new Thread(runnable);
thread.start();

Lambda运算
BinaryOperator<Integer> add = (x, y) -> x + y;
Integer x = add.apply(20, 30);
Lambda统计
String name[] = {"张三", "李四", "王五", "孙刘", "赵强", "李明", "赵强", "汪汪"};
long num = Arrays.stream(name).filter(x -> x.equals("赵强")).count();
Lambda数组去重并转化成集合存储
String name[] = {"张三", "李四", "王五", "孙刘", "赵强", "李明", "赵强", "汪汪"};
List<String> stringList = Arrays.stream(name).filter(x -> !x.equals("赵强")).collect(toList());
Lambda数组去重,并对元素加后缀
String name[] = {"张三", "李四", "王五", "孙刘", "赵强", "李明", "赵强", "汪汪"};
List<String> stringList2 = Arrays.stream(name).filter(x -> !x.equals("赵强")).map(y -> y + "加后缀:").collect(toList());
Lambda数组求和
int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 3, 4, 5, 6, 7, 8, 9, 10 };
        int count = 0;
        // for循环
        for (int i = 0; i < a.length; i++) {
            count += a[i];
        }
        // foreach
        count = 0;
        for (int i = 0; i < a.length; i++) {
            count += a[i];
        }
        // Lambda
        int num = Arrays.stream(a).reduce(0, (b, c) -> b + c);
Lambda提取对象属性并实现拼接
List<User> userList = asList(new User("张三" , 10) , new User("李四" , 10) , new User("王五" , 13));
String result = userList.stream().map(User::getUsername).collect(Collectors.joining("," , "[" , "]"));
输出结果:[张三,李四,王五]
Lambda分组
List<User> userList = asList(new User("张三" , 10) , new User("李四" , 10) , new User("王五" , 13));
Stream<User> userStream = userList.stream();
Map<Integer , List<String>> integerStringMap = userStream.collect(groupingBy(user->user.getAge() , mapping(User::getUsername , toList())));
System.out.println(integerStringMap.toString());
输出结果:{10=[张三, 李四], 13=[王五]}
stream流操作
//去重 distinct() 去重;collect(Collectors.toList());封装成集合
List<Person> distinctList = list.stream().distinct().collect(Collectors.toList());

//排序  sorted((第一个对象,第二个对象)->返回值)  (升降序看是第几个对象与第几个对象比较)
List<Person> sortedList = list.stream().sorted((o1,o2)->o1.getAge()-o2.getAge()).collect(Collectors.toList());

//过滤  filter(item->{})   item为每一项 按照自己的需求来筛选list中的数据
List<Person> filterList = list.stream().filter(item->item.getAge()>3).collect(Collectors.toList());

//map() 提取对象中的某一元素  用每一项来获得属性(也可以直接用  对象::get属性())
List<String> mapList1 = list.stream().map(Person::getName).collect(Collectors.toList());
List<String> mapList2 = list.stream().map(item->item.getName()).collect(Collectors.toList());

//统计 sum() mapToDouble() 转换成double
//其他聚合函数max(),min(),average()
double sum = list.stream().mapToDouble(Person::getAge).sum();

//分组   Collectors.groupingBy(属性名)
Map<Integer, List<Person>> map = list.stream().collect(Collectors.groupingBy(Person::getAge));

//多重分组 Collectors.groupingBy(属性,Collectors.groupingBy(属性))
Map<String, Map<Integer, List<Person>>> map2 = list.stream().collect(Collectors.groupingBy(t->t.getName(),Collectors.groupingBy(t->t.getAge())));

//分组并计算综合 Collectors.summarizingLong()
Map<String, Map<Integer, LongSummaryStatistics>> map3 = list.stream().collect(Collectors.groupingBy(t->t.getName(),Collectors.groupingBy(t->t.getAge(),Collectors.summarizingLong(Person::getSize))));

//根据对象的某个字段进行去重
List<User> result = userLists.stream().collect(
            Collectors.collectingAndThen(
                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.name()))),
                ArrayList::new));
//指定key-value,value是对象中的某个属性值
Map<Integer,String> userMap1 = userList.stream().collect(Collectors.toMap(User::getId,User::getName));
//指定key-value,value是对象本身,User->User 是一个返回本身的lambda表达式
Map<Integer,User> userMap2 = userList.stream().collect(Collectors.toMap(User::getId,User->User));
//指定key-value,value是对象本身,Function.identity()是简洁写法,也是返回对象本身
 Map<Integer,User> userMap3 = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
//指定key-value,value是对象本身,Function.identity()是简洁写法,也是返回对象本身,key 冲突的解决办法,这里选择第二个key覆盖第一个key
 Map<Integer,User> userMap4 = userList.stream().collect(Collectors.toMap(User::getId, Function.identity(),(key1,key2)->key2));



  • 我的微信
  • 加好友一起交流!
  • weinxin
  • 微信公众号
  • 关注公众号获取分享资源!
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: