lambda表达式是一个可以传递执行的代码块。这是一些编程语言的常见功能,例如Lisp,Python,Scala等。但在Java 8之前,我们不能在Java中做同样的事情。如果我们想要执行一个代码块,我们需要创建一个对象并传递对象,例如使用策略设计模式。从Java 8开始,lambda表达式使我们能够将功能视为方法参数并传递一段代码。Java 8中的Lambda表达式非常强大,因此非常引人注目。
排序
import java.util.stream.Stream;
public class SortLambda {
public static void main(String[] args) {
User u1 = new User("Max", "0", 50);
User u2 = new User("Rocky", "1", 30);
User u3 = new User("Bear", "0", 40);
User[] uArray = { u1, u2, u3 };
Stream<User> uStream = Stream.of(uArray);
Stream<User> sortedUserStream = uStream.sorted((User m, User n) -> Integer.compare(m.getAge(), n.getAge()));
sortedUserStream.forEach(d -> System.out.print(d));
}
@Data
class User{
private String name;
private String sex;
private Integer age;
}
}
**
转换流
**
map()方法是一个中间操作。它返回一个流,该流包含将给定函数应用于流中每个元素的结果。
下面的代码返回一个Integers流,它是应用String.length()方法的结果。
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class JavaMap {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("java");
list.add("php");
list.add("python");
//map function
Stream<Integer> stream = list.stream().map(p -> p.length());
Integer[] lengthArr = stream.toArray(Integer[]:: new);
for(int a: lengthArr){
System.out.println(a);
}
}
}
filter()方法是一个中间操作。它返回一个流,该流由与该给定条件匹配的此流的元素组成。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class JavaFilter<T> {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("java");
list.add("php");
list.add("python");
list.add("lisp");
list.add("c++");
//filter function
Stream<String> stream = list.stream().filter(p -> p.length() > 3);
String[] arr = stream.toArray(String[]::new);
System.out.println(Arrays.toString(arr));
}
}
减少流
Java 8 Stream API包含一组终端操作(例如,average,sum,min,max和count),它们通过组合流的元素返回一个值。这种终端操作称为还原操作。除了那些终端操作之外,JDK还提供了通用的简化方法 - 本文reduce()将对此进行描述。
Stream.reduce()的一个简单示例
List<String> list = new ArrayList<String>();
list.add("java");
list.add("php");
list.add("python");
list.add("perl");
list.add("c");
list.add("lisp");
list.add("c#");
Stream<String> wordStream = list.stream();
我们可以使用以下代码来获取列表中字符串长度的总和:
int s = wordStream.map(s -> s.length())
.mapToInt(Integer::new)
.sum();
System.out.println(s);
我们也可以使用Stream.reduce()方法,这是一种更通用的方法:
Stream<Integer> lengthStream = wordStream.map(s -> s.length());
Optional<Integer> sum = lengthStream.reduce((x, y) -> x + y);
sum.ifPresent(System.out::println);
Stream.reduce()将输入作为累加器函数,它接受两个参数:缩减的部分结果(在这种情况下,到目前为止所有处理过的整数的总和)和流的下一个元素(在本例中为整数) )。它返回一个新的部分结果。在这种情况下,累加器函数是一个lambda表达式,它添加两个Integer值并返回一个Integer值。
您也可以使用:而不是使用lambda表达式:
Optional<Integer> sum = lengthStream.reduce(Integer::sum);
收集流
我们也可以收集结果,而不是将流减少到一个值。我们可以使用Stream.collect()方法将结果收集到数组,集合/列表或映射中。
1.将流结果收集到数组
List<String> list = new ArrayList<String>();
list.add("java");
list.add("php");
list.add("python");
Stream<String> wordStream = list.stream();
Stream<Integer> lengthStream = wordStream.map(s -> s.length());
Integer[] lenArr = lengthStream.toArray(Integer[]::new);
System.out.println(Arrays.toString(lenArr));
2.将流结果收集到列表/集
使用将结果收集到列表中Collectors.toList()。
List<Integer> intList= lengthStream.collect(Collectors.toList());
使用将结果收集到列表中Collectors.toSet()。
Set<Integer> intSet= lengthStream.collect(Collectors.toSet());
我们还可以指定要使用的集合类型,如下所示:
TreeSet<Integer> intSet= lengthStream.collect(Collectors.toCollection(TreeSet::new));
3.将流结果收集到map
List<String> list = new ArrayList<String>();
list.add("java");
list.add("php");
list.add("python");
Stream<String> wordStream = list.stream();
// to map
Map<String, Integer> map = wordStream.collect(Collectors.toMap(Function.identity(), s->s.length()));
System.out.println(map);