一、 lambda 表达式
1. 应用场景
集合框架:使用 Lambda 表达式可以方便地进行集合元素的遍历、筛选和转换等操作。如:
public void getList() {
List<String> list = new ArrayList<>();
list.add("你好");
list.add("派大星");
list.add("1");
list.add("2");
list.forEach(x -> System.out.println(x));
}
排序:Java 8 中新增的 Comparator
接口支
Collections.sort(list,(x,y) -> x.compareTo(y)); // 排序操作 从小
并行计算,在java8 中,新增Stream接口可以对集合进行操作,例如
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int sum = list.parallelStream().mapToInt(x -> x).sum();
GUI开发:JavaFX 中大量使用了 Lambda 表达式来实现事件监听器等功能,可以大大简化代码。例如:
Button button = new Button("Say Hello");
button.setOnAction(event -> System.out.println("Hello World!"));
/**
使用 Lambda 表达式为按钮控件添加了一个单击事件处理器,在单击时打印出 "Hello World!"。
*/
2.、语法格式
针对的是 函数式接口(只有一个方法的接口)
- 具体实现的功能3. 具体实验功能,如果有多个语句,则使用{}包裹
(参数) -> {
语句1;> 左边为参数列表};
-> 右边为具体实现功能
1. 无参数
() -> 实现功能
2. 有参数
(参数) ->
语句2;
3、例子
@Test
public void compareEmployee() { // 对Empolyee对象进行排序
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("张三",19));
employees.add(new Employee("李四",18));
employees.add(new Employee("赵武",22));
Collections.sort(employees,(x,y) -> {
if (x.getAge() == y.getAge()) {
return x.getName().compareTo(y.getName());
}else {
return Integer.compare(x.getAge(), y.getAge());
}
});
employees.forEach(x -> System.out.println(x));
}
4. 四大内置函数式接口
1. Consumer 接口
Consumer
接口表示一个可以接受单个输入参数并且不返回结果的操作。它包含一个名为 accept
的抽象方法,用于执行该操作。常见的用途是对每个元素应用一个操作,例如进行打印或修改等处理。
2. 接口Supplier
Supplier
接口表示一个可以产生单个结果值的操作。它包含一个名为 get
的抽象方法,无需任何输入参数,用于生成输出结果。
@Test
public void fourFunctionInterface() {
Supplier supplier = ()-> new Date().getDate();
System.out.println(supplier.get());
}
3. Function 接口
Function
接口表示一个可以接受单个输入参数,并且将其转换为单个输出结果的操作。它包含一个名为 apply
的抽象方法,用于执行转换操作。
// T 为单参数,R未返回类型
public interface Function<T, R> {
R apply(T t);
}
// 样例
Function<String,Integer> function = (s) -> Integer.parseInt(s);
System.out.println(function.apply("123"));
4、Predicate 接口
Predicate
接口表示一个可以接受单个输入参数并返回布尔值结果的操作。它包含一个名为 test
的抽象方法,用于执行操作并返回布尔值结果。
public interface Predicate<T> {
boolean test(T t);
}
Predicate<Integer> pred = x -> x > 0;
System.out.println(pred.test(1)); // 输出 true
5、方法引用
若 Lambda 体中方法内容已经实现了,可以使用 “方法引用” ,即 lambda 表达式 另一种表达形式。
注意:实例方法中的参数列表及返回值,要与函数式接口的方法的参数列表及返回值一致。
语法格式
1. 对象::实例方法名。
2. 类::静态方法名。
3. 类::实例方法名。(lambda 表达式中,第一个参数是调用方法的,第二个参数是实例方法的参数时,可以使用)。
@Test
public void test2() {
BiPredicate<String,String> b = (x,y) -> x.equals(y); // 判断两个字符串是否相等
// 方法引用 第一个参数时实例方法的调用者,第二个参数是实例方法的参数
BiPredicate<String ,String> b1 = String::equals;
}
6、构造器引用
二、StreamAPI【数组】
在Java中的Stream中,惰性求值(Lazy Evaluation)代表了Stream操作的一种特性。Stream是一种用于对集合进行处理的高级抽象,它提供了一种流式操作的方式。
当使用Stream对集合进行操作时,通常会有两类操作:惰性操作和终端操作。惰性操作指的是在Stream上进行的中间操作,它们不会立即执行,而是在终端操作触发时才进行计算。而终端操作则是最终触发计算并产生结果的操作。
具体而言,Stream的惰性求值意味着在进行中间操作时,并不会立即对源数据进行计算或处理。相反,它会记住这些操作,直到遇到一个终端操作时,才会一次性按需计算所有的中间操作,并生成最终结果。
1. 创建stream流的方法
1.通过Collection系列集合创建 stream 或 parallelStream
Collection<String> collection = new ArrayList<>();
Stream<String> stream = collection.stream();
2. 通过 Arrays 中的静态方法中 stream(T[] t) 创建stream对象。
int[] arr = new int[5];
IntStream stream1 = Arrays.stream(arr);
3. 通过stream的静态方法中 of 实现创建Steam对象。
Stream<Object> stream2 = Stream.of("1","2","3");
// 参数为数组
4. 通过迭代 创建无限流 0 起始值 对其 +2。
Stream<Integer> iterate = Stream.iterate(0, x -> x + 2);
iterate.limit(10).forEach(System.out::print);
5. 通过生成 创建无限流
Stream<Double> generate = Stream.generate(() -> Math.random());
generate.limit(10).forEach(System.out::println);
2. stream操作
a. 筛选和切片
1. filter 过滤操作,接受lambda,筛选出返回true的元素。
2. limit (n):切片操作,取出前n位个元素.
3. skip(n): 跳过前n个元素。
4. distinct:把数组中的数据,进行去重。
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("张三",19));
employees.add(new Employee("李四",18));
employees.add(new Employee("赵武",22));
employees.stream().filter(e -> e.getAge() > 10).limit(1).
skip(2).distinct().forEach(System.out::println);
b. 映射
1. Map
返回值类型:map操作将每个元素映射为一个新的值,并返回由映射结果组成的新Stream。
用法:适用于一对一的映射关系,将Stream中的每个元素通过指定的映射函数进行转换。
实例:
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("aaa",19));
employees.add(new Employee("bbb",18));
employees.add(new Employee("ccc",22));
// 将其中每一个name 转换位大写
employees.stream().map(e -> e.getName().toUpperCase()).forEach(System.out::print);
2. flatMap
返回值类型:flatMap操作将每个元素映射为一个Stream,然后将所有生成的Stream连接成一个新的Stream。
用法:适用于一对多的映射关系,将Stream中的每个元素映射为一个Stream,并将这些Stream合并成一个新的Stream。
实例:
List<List<Integer>> numbers = Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3, 4));
Stream<Integer> flattenedStream = numbers.stream().flatMap(List::stream);;
flattenedStream.forEach(System.out::println);
运行结果
c. 排序
排序操作
* sorted(Comparable) - 自然排序
* sorted(Comparator) - 自定义排序 指定方法
实例
employees.stream().sorted((e1,e2) -> {
return -Integer.compare(e1.getAge(), e2.getAge());
}).forEach(System.out::println);
d. 终止操作
1. 查找与匹配
1. allMatch 匹配所有的元素,返回所有元素是否满足其lambda表达式中符号条件的 Boolean值。
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("张三",19));
employees.add(new Employee("李四",18));
employees.add(new Employee("赵武",22));
// 是否 元素的年龄全部满足 大于10 返回 true
System.out.println(employees.stream().allMatch(t -> t.getAge() > 10));
2. anyMatch 匹配某一个元素,当元素有一个满足其中表达式时,就会返回true。
System.out.println(employees.stream().anyMatch(T -> T.getAge() > 20));
// 元素其中,是否有满足条件的 boolean值
3. noneMatch 没有匹配条件的元素,返回true,否则 false。
// 没有匹配条件的元素,返回true,否则 false
boolean b = stream.noneMatch(t -> t.getAge() > 30);
System.out.println(b);
4. findFirst findAny
// findFirst 返回第一个元素
Optional<Employee> first = stream.findFirst();
System.out.println(first.get());
// findAny 返回多个元素 parallelStream 并行流操作 可能每一次返回的值都不一样
Stream<Employee> employeeStream = employees.parallelStream();
Optional<Employee> any = employeeStream.findAny();
System.out.println(any.get());
5. min 获取最小值,max 获取最大值,count统计元素个数。
// min 获取最小值 参数接受比较直
Optional<Employee> min = stream.min((x,y) -> Integer.compare(x.getAge(),y.getAge()));
System.out.println(min.get());
// max 获取最大值 参数接受 lambda 表达式
Optional<Employee> max = stream.max((x,y) -> Integer.compare(x.getAge(),y.getAge()));
System.out.println(min.get());
// 返回元素的个数
long count = stream.count();
System.out.println(count);
2. 归并与收集
List<Integer> list = Arrays.asList(1, 2, 3);
Integer reduce = list.stream().reduce(0, (x, y) -> x + y);
System.out.println(reduce);
收集器
// 收集 员工姓名到 集合中
List<String> collect = stream.map(Employee::getName)
.collect(Collectors.toList());
System.out.println(collect);
三、接口的静态方法及默认方法
1. 类优先
四、时间API
解决了多线程安全问题
1. LocalDate
2. LocalTime
3.LocalDateTime
public void newDate() {
// 获取当前系统时间
LocalDateTime now = LocalDateTime.now();
// LocalDateTime对象提供过了 获取各个时间的部分
int hour = now.getHour();
System.out.println(hour);
// 指定时间段
LocalDateTime of = LocalDateTime.of(22,23,11,16,12);
System.out.println(of);
// 加上时间段 返回新实例
// LocalDateTime plus = of.plus();
// 减对应的时间段,返回新的实例
// of.minus()
// 1970-1-1 到 默认获取 UTC 时区的毫秒数
Instant now1 = Instant.now();
// TemporalAdjusters.
LocalDateTime h1 = LocalDateTime.now();
// 把时间段改为 下一周的周日
LocalDateTime with = h1.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
}
// 时间日期的格式化
@Test
public void format() {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd hh-mm-ss");
LocalDateTime now = LocalDateTime.now();
String format = dateTimeFormatter.format(now);
}