在日常工作中使用lambda表达可以较少与业务代码无关的代码,提高代码的可读性及使用很少的代码即可完成相关功能的代码编写。 数据准备 在使用这些方法之前先准备一些测试数据。测试数据如下: 新建的student的javabean如下:
public class Student { private String name; private int age; @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }在main方法中添加新建一个List的模拟数据.
List<Student> students = new ArrayList<>(); students.add(new Student("user1", 18)); students.add(new Student("user2", 26)); students.add(new Student("user3", 30)); students.add(new Student("user4", 10)); students.add(new Student("user4", 10));常用方法
map方法 map方法可以实现流的转换,如我们原先的流为R对象,通过map方法我们将流中的R对象转为T .map方法的源码如下: // 接收一个Function的函数式接口, <R> Stream<R> map(Function<? super T, ? extends R> mapper);其中Function的源码如下: 接收T,R两个类型的参数,最后返回R类型的参数.
@FunctionalInterface public interface Function<T, R> { R apply(T t); default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); } default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); } static <T> Function<T, T> identity() { return t -> t; } }使用map的demo:
List<Integer> list = students.stream().map(x -> x.getAge()). collect(Collectors.toList()); list.forEach(x -> System.out.println(x)); // 18,26,30,10,10和map功能相类似的有mapInt和mapToLong或者mapToDouble,他们都返回特定的返回值类型.
List<Integer> list = students.stream().mapToInt(x -> x.getAge()) // 必须有mapToObj,因为mapToInt已经是返回一个IntStream,已经明确返回的类型 // 已经没有泛型了明确了int,而Collectors.toList,需要泛型类型的流,故 // 必须使用mapToObj方法返回有泛型的流 .mapToObj(x -> x). collect(Collectors.toList()); list.forEach(x -> System.out.println(x)); // 18,26,30,10,10 distinct方法 distinct方法具有去重的功能,使用demo如下: List<Student> list = students.stream().distinct(). collect(Collectors.toList()); list.forEach(x -> System.out.println(x)); filter方法 filter方法具有过滤的功能,类型与我们if中的条件一样只有符合了条件才能被保留下来,不满足则进行过滤。 filter源码如下: // 传入一个Predicate的函数式接口 Stream<T> filter(Predicate<? super T> predicate); // 而Predicate根据入参的T返回boolean类型filter使用demo如下:
List<Student> list = students.stream().filter(x -> x.getAge() > 25). collect(Collectors.toList()); list.forEach(x -> System.out.println(x)); flapMap方法 flapMap方法也可以做一些流的转换,只是和map不同的是它Function明确了返回值类型。 List<Student> students = new ArrayList<>(); students.add(new Student("user1", 18,Arrays.asList(100,98,98))); students.add(new Student("user2", 26,Arrays.asList(100,98,98))); students.add(new Student("user3", 30,Arrays.asList(100,98,98))); students.add(new Student("user4", 10, Arrays.asList(100,98,98))); students.add(new Student("user4", 10,Arrays.asList(100,98,98))); List<Integer> list = students.stream().flatMap(x -> x.getCourses().stream()). collect(Collectors.toList()); list.forEach(x -> System.out.println(x)); sorted方法 sorted方法提供了排序功能,也可以实现自定义排序。 List<Integer> list = students.stream().map(Student::getAge) .sorted(). collect(Collectors.toList()); list.forEach(x -> System.out.println(x)); limit方法 limit方法作用限制输出值的个数,入参是限制的大小,demo如下: List<Student> list = students.stream().limit(2). collect(Collectors.toList()); list.forEach(x -> System.out.println(x)); reduce方法 reduce方法允许我们在循环中,对一些值进行一些叠加操作,demo如下: Integer sum= students.stream().map(Student::getAge). reduce((x,y) -> x+y).orElse(0); System.out.println(sum); peek方法 peek方法是没有任何返回值滴,但是可以做一些日志的打印功能,demo如下: List<Student> list = students. stream().peek(x -> System.out.println(x)) .collect(Collectors.toList()); findFirst方法 findFirst方法去除第一个值,和filter 方法一起使用可以有更不错的效果,demo如下: int list = students. stream().filter(x -> x.getAge() > 28).findFirst().get().getAge(); System.out.println(list);以上是lambda表达式常用的方法。
