今天只谈Lambda
Lambda表达式是推动Java 8发布的最重要的新特性。是继泛型(Generics
)和注解(Annotation
)以来最大的变化。使用 Lambda 表达式可以使代码变的更加简洁紧凑。让 java 也能支持简单的函数式编程。
Lambda 表达式是一个匿名函数,java 8 允许把函数作为参数传递进方法中。
Stream源码

/**
* 返回一个串行流
*/
default Stream<E> stream()
/**
* 返回一个并行流
*/
default Stream<E> parallelStream()
/**
* 返回T的流
*/
public static<T> Stream<T> of(T t)
/**
* 返回其元素是指定值的顺序流。
*/
public static<T> Stream<T> of(T... values) {
return Arrays.stream(values);
}
/**
* 过滤,返回由与给定predicate匹配的该流的元素组成的流
*/
Stream<T> filter(Predicate<? super T> predicate);
/**
* 此流的所有元素是否与提供的predicate匹配。
*/
boolean allMatch(Predicate<? super T> predicate)
/**
* 此流任意元素是否有与提供的predicate匹配。
*/
boolean anyMatch(Predicate<? super T> predicate);
/**
* 返回一个 Stream的构建器。
*/
public static<T> Builder<T> builder();
/**
* 使用 Collector对此流的元素进行归纳
*/
<R, A> R collect(Collector<? super T, A, R> collector);
/**
* 返回此流中的元素数。
*/
long count();
/**
* 返回由该流的不同元素(根据 Object.equals(Object) )组成的流。
*/
Stream<T> distinct();
/**
* 遍历
*/
void forEach(Consumer<? super T> action);
/**
* 用于获取指定数量的流,截短长度不能超过 maxSize 。
*/
Stream<T> limit(long maxSize);
/**
* 用于映射每个元素到对应的结果
*/
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
/**
* 根据提供的 Comparator进行排序。
*/
Stream<T> sorted(Comparator<? super T> comparator);
/**
* 在丢弃流的第一个 n元素后,返回由该流的 n元素组成的流。
*/
Stream<T> skip(long n);
/**
* 返回一个包含此流的元素的数组。
*/
Object[] toArray();
/**
* 使用提供的 generator函数返回一个包含此流的元素的数组,以分配返回的数组,以及分区执行或调整大小可能需要的任何其他数组。
*/
<A> A[] toArray(IntFunction<A[]> generator);
/**
* 合并流
*/
public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
Lambda 实战
1、List<String>
package com.example.demo.lambda; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; /** * @Author HandSomeHeLin * @Date 2022/1/5 20:50 * @Description Lambda 实战 */ public class lambdaDemo { public static void main(String[] args) { // Lambda遍历List<String> List<String> strings = Arrays.asList("abc", "def", "gkh", "abc"); // 1、filter(过滤条件) strings = strings.stream().filter(s -> s.equals("abc")).collect(Collectors.toList()); // 输出:[abc, abc] // 2、forEach(遍历元素) strings.forEach(System.out::println); // 输出: // abc // def // gkh // abc // 3、limit(限制显示个数) strings = strings.stream().limit(2).collect(Collectors.toList()); // 输出:[abc, def] // 4、map(操作每个元素) strings = strings.stream().map(s -> s+"22").collect(Collectors.toList()); // 输出:[abc22, def22, gkh22, abc22] // 4、sorted(排序) strings = strings.stream().sorted().collect(Collectors.toList()); // 输出:[abc, abc, def, gkh] } }
2、List<Integer>
package com.example.demo.lambda; import java.util.Arrays; import java.util.IntSummaryStatistics; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; /** * @Author HandSomeHeLin * @Date 2022/1/5 20:50 * @Description Lambda 实战 */ public class lambdaDemo { public static void main(String[] args) { // Lambda遍历List<Integer> List<Integer> numbers = Arrays.asList(1, 2, 5, 4); // mapToInt(统计) IntSummaryStatistics statistics = numbers.stream().mapToInt(x->x).summaryStatistics(); System.out.println("最大值:"+statistics.getMax()); System.out.println("最小值:"+statistics.getMin()); System.out.println("平均数:"+statistics.getAverage()); System.out.println("总和:"+statistics.getSum()); } }
3、List对象类型
实体类
package com.example.demo.lambda; import lombok.*; import java.io.Serializable; /** * @Author HandSomeHeLin * @Date 2022/1/5 21:44 * @Description User */ @Data public class User implements Serializable { private Integer id; private String name; private Integer age; }
package com.example.demo.lambda; import lombok.Data; import java.io.Serializable; import java.math.BigDecimal; /** * @Author HandSomeHeLin * @Date 2022/1/6 16:39 * @Description Item */ @Data public class Item implements Serializable { private String name; private int age; private BigDecimal value; public Item(String name, int age, BigDecimal value) { this.name = name; this.age = age; this.value = value; } }
测试类
package com.example.demo; import com.example.demo.lambda.Item; import com.example.demo.lambda.User; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; @SpringBootTest class DemoApplicationTests { // 构建用户信息 private List<User> getUsers(){ List<User> users = new ArrayList<>(); for (int i = 1; i < 5; i++) { User u = new User(); u.setId(i); u.setAge(18+i); u.setName("name_"+i); users.add(u); } return users; } // 构建水果信息 private List<Item> getFruits(){ return Arrays.asList( new Item("apple", 10, new BigDecimal("9.99")), new Item("banana", 20, new BigDecimal("19.99")), new Item("orang", 10, new BigDecimal("29.99")), new Item("watermelon", 10, new BigDecimal("29.99")), new Item("papaya", 20, new BigDecimal("9.99")), new Item("apple", 10, new BigDecimal("9.99")), new Item("banana", 10, new BigDecimal("19.99")), new Item("apple", 20, new BigDecimal("9.99"))); } /** * filter可以按照指定条件过滤数据 */ @Test void filter() { List<User> users = getUsers(); users.stream().filter(user -> user.getAge() > 20).forEach(System.out::println); } /** * match提供了多种匹配操作,允许检测指定的Predicate是否匹配整个Stream。 * 所有的匹配操作都是最终操作,并返回一个 boolean 类型的值 * allMatch 所有元素进行匹配 * noneMatch 没有元素进行匹配 * anyMatch 任意元素进行匹配 */ @Test void match() { List<User> users = getUsers(); boolean allCon = users.stream().allMatch(user -> user.getName().contains("name_1")); System.out.println("是否包含:" + allCon); boolean noCon = users.stream().noneMatch(user -> user.getName().contains("name_1")); System.out.println("是否包含:" + noCon); boolean anyCon = users.stream().anyMatch(user -> user.getName().contains("name_1")); System.out.println("是否包含:" + anyCon); } /** * limit可以限制集合展示个数 */ @Test void limit() { List<User> users = getUsers(); users.stream().limit(2).forEach(System.out::println); } /** * sorted可以根据属性进行排序 */ @Test void sorted() { List<User> users = getUsers(); users.stream() // 筛选不为空对象 .filter(Objects::nonNull) // 倒序reversed() .sorted(Comparator.comparing(User::getAge).reversed()) .collect(Collectors.toList()) .forEach(System.out::println); } /** * 计算最大值、最小值、总和、统计以及平均值 */ @Test void maxAndMinAndAvg() { List<User> users = getUsers(); // 方式一 User userMax = users.stream().max(Comparator.comparing(User::getAge)).get(); System.out.println("年龄最大的是 :" + userMax); User userMin = users.stream().min(Comparator.comparing(User::getAge)).get(); System.out.println("年龄最小的是 :" + userMin); int sum = users.stream().mapToInt(User::getAge).sum(); System.out.println("年龄的总和是 :" + sum); OptionalDouble avg = users.stream().mapToInt(User::getAge).average(); System.out.println("年龄平均值是 :" + avg.getAsDouble()); // 方式二 IntSummaryStatistics summaryStatistics = getUsers().stream().mapToInt(User::getAge).summaryStatistics(); System.out.println("最大年龄 : " + summaryStatistics.getMax()); System.out.println("最小年龄 : " + summaryStatistics.getMin()); System.out.println("平均年龄 : " + summaryStatistics.getAverage()); System.out.println("年龄总和 : " + summaryStatistics.getSum()); System.out.println("总的统计多少个人 : " + summaryStatistics.getCount()); } /** * 分组统计 */ @Test void count() { List<Item> items = getFruits(); // 通过名称进行分组, 统计有多少个 Map<String, Long> nameMaps = items .stream() .collect(Collectors.groupingBy(Item::getName, Collectors.counting())); System.out.println(nameMaps); // 通过名称分组, 质量求和 Map<String, Integer> nqtsMaps = items .stream() .collect(Collectors.groupingBy(Item::getName, Collectors.summingInt(Item::getAge))); System.out.println(nqtsMaps); // 通过价格分组 输出: // {19.99=[Item(name=banana, age=20, value=19.99), Item(name=banana, age=10, value=19.99)], // 29.99=[Item(name=orang, age=10, value=29.99), Item(name=watermelon, age=10, value=29.99)], // 9.99=[Item(name=apple, age=10, value=9.99), Item(name=papaya, age=20, value=9.99), // Item(name=apple, age=10, value=9.99), Item(name=apple, age=20, value=9.99)]} Map<BigDecimal, List<Item>> priceMaps = items .stream() .collect(Collectors.groupingBy(Item::getValue)); System.out.println(priceMaps); // 通过价格分组, 转换结果集 List<Item> 为 Set<String> // {19.99=[banana], 29.99=[orang, watermelon], 9.99=[papaya, apple]} Map<BigDecimal, Set<String>> result = items .stream() .collect(Collectors.groupingBy(Item::getValue, Collectors.mapping(Item::getName, Collectors.toSet()))); System.out.println(result); } /** * 分区 * 分区是一种特殊的分组,结果 map 至少包含两个不同的分组——一个true,一个false * 例如,按照价格分组:大于 N,另一组小于 N */ @Test void partition() { List<Item> items = getFruits(); Map<Boolean, List<Item>> partitioned = items.stream().collect(Collectors.partitioningBy(e -> e.getValue().compareTo(new BigDecimal(20)) > 0)); System.out.println(partitioned); } /** * 分区2 * 也可以将 groupingBy 收集器传递给 partitioningBy 收集器来将联合使用分区和分组。 * 例如,你可以统计每个分区中的每个水果的占用数, 也就是比例 */ @Test void proportion() { List<Item> items = getFruits(); // 分区和统计一起 Map<Boolean, Map<String, Long>> result = items .stream() .collect(Collectors.partitioningBy(e -> e.getValue().compareTo(new BigDecimal(20)) > 0 , Collectors.groupingBy(Item::getName, Collectors.counting()))); System.out.println(result); } }
完结
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律