Lambda表达式
目录
一、语法
表达式-风格
(parameters) -> expression块-风格
- 特殊的是:返回值为void的单行方法调用不需要用括号环绕。
(parameters) -> { statements; }
二、使用
Lambda 表达式的使用需要借助于函数式接口,也就是说只有函数式接口出现地方,我们才可以将其用 lambda 表达式进行简化。
函数式接口定义:仅含有一个抽象方法的接口。
- 例子
- 函数式接口
@FunctionalInterface public interface Comparator<T> { int compare(T o1, T o2); } - 使用示例
Comparator<Apple> appleComparator =(Apple a1, Apple a2) -> a1.getWeight - a2.getWeight; appleComparator.compare(new Apple(200), new Apple(210));
- 例子
- 函数式接口
@FunctionalInterface public interface Runnable { public abstract void run(); } - 使用示例
// 不使用Lambda表达式: new Thread(new Runnable() { @Override public void run() { System.out.println("Before Java8, too much code for too little to do"); } }).start(); //使用Lambda表达式: new Thread( () -> System.out.println("In Java8, Lambda expression rocks !!") ).start();
三、常用函数式接口
- 函数式接口可以对现有的函数友好地支持 lambda,在JDK中已有一些函数式接口。
Predicate
适用场景:表示一个涉及类型T的布尔表达式。
接口源代码
public interface Predicate<T> { boolean test(T t); }使用示例
public static void main(args[]){ List fruits = Arrays.asList("西瓜", "哈密瓜", "杨梅", "苹果", "榴莲"); filter(languages, (str)->str.endsWith("瓜")); } public static void filter(List fruits, Predicate condition) { for(String fruit: fruits) { if(condition.test(fruit)) { System.out.println(fruit + " "); } } }
Consumer
适用场景:访问类型T的对象,对其执行某些操作。
接口源代码
public interface Consumer<T> { void accept(T t); }使用示例
Consumer<People> peopleConsumer = p -> System.out.println("我的名字叫" + p.getName()); appleWeighter.accept(new People("张三"));
Function
适用场景:将输入对象转换输出。
接口源代码
public interface Function<T, R> { R apply(T t); }使用示例
Function<People, String> AgeOfPeople = p -> p.getName() + "的年龄是" + p.getAge(); NameOfPeople.apply(new People("张三",12));
四、方法引用
静态方法的方法引用
- 不使用方法引用
Function<String, Integer> fun = s -> Integer.parseInt(s); - 使用方法引用
Function<String, Integer> fun = Integer::parseInt;
- 不使用方法引用
实例方法的方法引用
- 不使用方法引用
Function<String, Integer> fun = s -> s.length(); - 使用方法引用
Function<String, Integer> fun = String::length;
- 不使用方法引用
现存外部对象实例方法的方法引用
- 不使用方法引用
String s = "方法引用"; Supplier<Integer> len = () -> s.length(); - 使用方法引用
String s = "方法引用"; Supplier<Integer> len = s::length;
- 不使用方法引用
五、在流处理中使用Lambda表达式
forEach、limit、sorted
//使用 forEach 输出10个排序后的随机数 Random random = new Random(); random.ints().limit(10).sorted().forEach(System.out::println);map、collect
// 获取对应的平方数,结果转为集合 List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());filter、count
//获取空字符串的数量 List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); long count = strings.stream().filter(string -> string.isEmpty()).count();Collectors
List<String>strings = Arrays.asList("aaa", "", "bbb", "ccc", "","ddd");
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
- 统计结果的收集器(主要用于int、double、long等基本类型上)
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());