- A+
所属分类:Java
Lambda表达式的优缺点
优点:
- 简洁
- 易并行计算,特别适合便利结果,循环计算数值或者赋值的时候很方便
缺点:
- 若不用并行运算,很多时候计算方式速度没有传统的For循环快。
- 不容易使用Debug模式调试
- 在Lamdba语句中直接强制转换不方便
- 不可以再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));
- 我的微信
- 加好友一起交流!
-
- 微信公众号
- 关注公众号获取分享资源!
-