1. Lambda操作Collections
为引入Lambda表达式,Java8新增了java.util.funcion包,里面包含常用的函数接口,这是Lambda表达式的基础,Java集合框架也新增部分接口,以便与Lambda表达式对接。由于继承关系,他们相应的子类也都会继承这些新方法
框架的接口继承结构
1.1 Java8新加入的方法
接口类型 |
新加入的方法 |
Collection |
removeIf() forEach() spliterator() stream() parallelStream() |
List |
replaceAll() sort() |
Map |
getOrDefault() forEach() replaceAll() putIfAbsent() remove() replace() computeIfAbsent() computeIfPresent() compute() merge() |
由于继承关系,他们相应的子类也都会继承这些新方法。
2. 在Collection中使用Lambda
2.1 removeIf()
该方法签名为boolean removeIf(Predicate<? super E> filter),作用是删除容器中所有满足filter指定条件的元素。
java8以前的代码
ArrayList<Integer> integers = new ArrayList<>(Arrays.asList(20, 420, 170, 100, 140)); Iterator<Integer> iterator = integers.iterator(); while (iterator.hasNext()){ if (iterator.next() < 100){ iterator.remove(); } } System.out.println(integers);
/** * 输出:[420, 170, 100, 140] */
|
匿名内部类过度代码
ArrayList<Integer> integers = new ArrayList<>(Arrays.asList(20, 420, 170, 100, 140)); integers.removeIf(new Predicate<Integer>(){ @Override public boolean test(Integer number){ return number < 100; } });
|
Lambda代码
ArrayList<Integer> integers = new ArrayList<>(Arrays.asList(20, 420, 170, 100, 140)); integers.removeIf(number -> number < 100);
|
改写依据
removeIf要传入一个Predicate函数接口的实现类,Predicate是一个函数接口,里面只有一个待实现方法boolean test(T t)。根据Lambda的改写依据,可以省略函数接口实现类的类名和方法名,有参时,直接使用: 参数->{…},由于是单行代码块,{} 也可以省略
2.2 forEach()
签名为void forEach(Consumer<? super E> action),作用是对容器中的每个元素执行action指定的动作,其中Consumer是个函数接口。
- 使用示例:
假设有一个字符串列表,需要打印出其中所有长度小于3的字符串.
java8以前的代码
ArrayList<String> list = new ArrayList<>(Arrays.asList("PHP","JAVA","PYTHON","GO")); for(String str : list){ if(str.length() < 3){ System.out.println(str); } }
|
匿名内部类过度代码
ArrayList<String> list = new ArrayList<>(Arrays.asList("PHP","JAVA","PYTHON","GO")); list.forEach(new Consumer<String>(){ @Override public void accept(String str){ if(str.length() < 3) System.out.println(str); } });
|
Lambda代码
ArrayList<String> arrayList = new ArrayList<>(Arrays.asList("PHP", "JAVA", "PYTHON", "GO")); arrayList.forEach(str ->{ if (str.length() < 3){ System.out.println(str); } });
|
2.3 replaceAll()
该方法签名为void replaceAll(UnaryOperator operator),作用是对每个元素执行operator指定的操作,并用操作结果来替换原来的元素。其中UnaryOperator是一个函数接口,里面只有一个待实现函数T apply(T t)。
- 使用示例:
假设有一个字符串列表,将其中所有长度小于3的字符串 转为大写.
java8以前的代码
ArrayList<String> list = new ArrayList<>(Arrays.asList("PHP", "JAVA", "PYTHON", "GO")); for (int i = 0; i < list.size(); i++) { String str = list.get(i); if (str.length() < 3) { list.set(i, str.toLowerCase()); } } System.out.println(list);
|
匿名内部类过度代码
ArrayList<String> list = new ArrayList<>(Arrays.asList("PHP","JAVA","PYTHON","GO")); list.replaceAll(new UnaryOperator<String>(){ @Override public String apply(String str){ if(str.length() < 3){ return str.toLowerCase(); } return str; } }); System.out.println(list);
|
Lambda代码
ArrayList<String> arrayList = new ArrayList<>(Arrays.asList("PHP", "JAVA", "PYTHON", "GO")); list.replaceAll(str -> { if (str.length() < 3 ) { return str.toLowerCase(); } return str; }); System.out.println(list);
|
2.4 sort()
该方法定义在List接口中,方法签名为void sort(Comparator<? super E> c),该方法根据c指定的比较规则对容器元素进行排序。Comparator接口我们并不陌生,其中有一个方法int compare(T o1, T o2)需要实现,显然该接口是个函数接口。
- 使用示例:
假设有一个字符串列表,按照字符串长度对元素降序排序。
java8以前的代码
ArrayList<String> list = new ArrayList<>(Arrays.asList("PHP", "JAVA", "PYTHON", "GO")); Collections.sort(list, new Comparator<String>(){ @Override public int compare(String str1, String str2){ return str2.length()-str1.length(); } }); System.out.println(list);
|
Lambda代码
list.sort((str1,str2)->str2.length() - str1.length());
|
2.5 spliterator()
方法签名为Spliterator spliterator(),该方法返回容器的可拆分迭代器。从名字来看该方法跟iterator()方法有点像,我们知道Iterator是用来迭代容器的,Spliterator也有类似作用,但二者有如下不同:
- Spliterator既可以像Iterator那样逐个迭代,也可以批量迭代。批量迭代可以降低迭代的开销。
- Spliterator是可拆分的,一个Spliterator可以通过调用Spliterator trySplit()方法来尝试分成两个。一个是this,另一个是新返回的那个,这两个迭代器代表的元素没有重叠。
可通过(多次)调用Spliterator.trySplit()方法来分解负载,以便多线程处理。
2.6 stream()和parallelStream()
stream()和parallelStream()分别返回该容器的Stream视图表示,不同之处在于parallelStream()返回并行的Stream。Stream是Java函数式编程的核心类,我们会在后面章节中学习。
以上内容摘自关于Java Lambda表达式看这一篇就够了