赞
踩

Lambda 是一个匿名函数,我们可以把 Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升
( o1 , o2 ) -> Integer.compare( o1 , o2 )
Runnable r = () -> System.out.println("hello");
Consumer<String> consumer = (args) -> System.out.println(args);
Consumer<String> consumer2 = args -> System.out.println(args);
BinaryOperator<Long> bo = (Long x,Long y) -> {
System.out.println("实现函数接口方法!");
return x + y;
};
BinaryOperator<Long> bio = (Long x,Long y) -> x + y;
BinaryOperator<Long> bio = (x, y) -> x + y;

@FunctionalInterface
public interface MyInterface {
public String getValue();
}
@FunctionalInterface
public interface MyInterface<T> {
public T getValue(T t);
}
注意:为了将 Lambda 表达式作为参数传递,接收Lambda 表达式的参数类型必须是与该 Lambda 表达式兼容的函数式接口的类型。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FZg2BxkQ-1691226971695)(https://cdn.nlark.com/yuque/0/2023/png/28753938/1690982576323-da8afac2-23a2-4d9e-bbfe-59cb77780101.png#averageHue=%23fdf9f7&clientId=u7db73e94-b1fb-4&from=paste&height=314&id=ua254661d&originHeight=393&originWidth=1107&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=73070&status=done&style=none&taskId=ucdb6ab1b-b322-4800-bd24-f958e534228&title=&width=885.6)]

@Test public void testConsumer() { // 消费型接口Consumer<T> void accept(T t) buyCar(265000.00, new Consumer<Double>() { @Override public void accept(Double aDouble) { System.out.println("买车花费了:" + aDouble); } }); System.out.println("使用lambda表达式如下"); buyCar(99999.99, money -> System.out.println("买车花费了:" + money)); } /** * 利用Consumer 实现消费 * @param money 金额 * @param con 所消费金额 */ public void buyCar(Double money, Consumer<Double> con) { con.accept(money); }

@Test public void testPredicate() { // 断定型接口Predicate<T> boolean test(T t) List<String> list = Arrays.asList("aabb", "bbcc", "ccdd", "aadd"); List<String> res = filterString(list, new Predicate<String>() { @Override public boolean test(String s) { return s.contains("aa"); } }); System.out.println("过滤后:" + res); System.out.println("使用lambda表达式如下"); List<String> res2 = filterString(list, s -> s.contains("aa")); System.out.println("过滤后:" + res2); } /** * 利用Predicate 实现过滤 * @param list 原数组 * @param pre 约束条件 * @return 过滤后数组 */ public List<String> filterString(List<String> list, Predicate<String> pre) { List<String> result = new ArrayList<>(); for (String s : list) { if (pre.test(s)) { result.add(s); } } return result; }
供给型接口Supplier T get()![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p7w6CR08-1691226971697)(https://cdn.nlark.com/yuque/0/2023/png/28753938/1690986218640-a31f6463-910c-4a1e-afa7-23d07779bcf7.png#averageHue=%23a0b6d5&clientId=u7db73e94-b1fb-4&from=paste&height=387&id=ua4c19adb&originHeight=484&originWidth=775&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=122303&status=done&style=none&taskId=u84321d21-223c-4690-997a-6fe6a7d0fa7&title=&width=620)]](https://img-blog.csdnimg.cn/177370dceadd4c7fab7047d60744538d.png)
当要传递给 Lambda 体的操作,已经有实现的方法了,可以使用方法引用!
方法引用,本质上也是 Lambda 表达式,而 Lambda 表达式作为函数式接口的实例。所以,方法引用也是函数式接口的实例。
方法引用使用的要求:要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法的形参列表和返回值类型相同!(情况三特殊)
情况一 对象 :: 非静态方法
情况二 类 :: 静态方法
情况三 类 :: 非静态方法
package com.mv.java8.basic; import org.junit.Test; import java.io.PrintStream; import java.util.Arrays; import java.util.Comparator; import java.util.Date; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; /** * 方法引用 * 1.使用情景:当要传递给 Lambda 体的操作,已经有实现的方法了,可以使用方法引用! * 2.方法引用,本质上也是 Lambda 表达式,而 Lambda 表达式作为函数式接口的实例。所以,方法引用也是函数式接口的实例。 * 3.使用格式: 类 (或对象) :: 方法名 * 4.具体分为以下三种情况 * 5.方法引用使用的要求:要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法的形参列表和返回值类型相同! * 对象 :: 非静态方法 * 类 :: 静态方法 * 类 :: 非静态方法 * * @author wv * @version V1.0 * @date 2023/8/3 19:45 */ public class MethodRefTest { @Test public void test01() { // 情况一 : 对象 :: 实例方法 // Consumer 中的 void accept(T t) // PrintStream 中的 void println(T t) Consumer<String> con1 = str -> System.out.println(str); con1.accept("hello"); System.out.println("使用方法引用如下:"); // PrintStream printStream = System.out; // Consumer<String> con2 = printStream::println; Consumer<String> con2 = System.out::println; con2.accept("world"); } @Test public void test02() { // 情况二 : 类 :: 静态方法 // Comparator 中的 int compare(T t1, T t2) // Integer 中的 int compare(T t1, T t2) Comparator<Integer> com1 = (a, b) -> Integer.compare(a, b); System.out.println(com1.compare(10, 5)); System.out.println("使用方法引用如下:"); Comparator<Integer> com2 = Integer::compare; System.out.println(com1.compare(5, 10)); // Function 中的 apply(T t) // Math 中的 Long round(Double d) Function<Double, Long> func = new Function<Double, Long>() { @Override public Long apply(Double aDouble) { return Math.round(aDouble); } }; System.out.println(func.apply(3.14)); System.out.println("使用方法引用如下:"); Function<Double, Long> func1 = Math::round; System.out.println(func1.apply(3.14)); } @Test public void test03() { // 情况二 : 类 :: 非静态方法 // Comparator 中的 int compare(T t1, T t2) // String 中的 int t1.compareTo(t2) Comparator<String> com1 = (a, b) -> a.compareTo(b); System.out.println(com1.compare("a", "b")); System.out.println("使用方法引用如下:"); Comparator<String> com2 = String::compareTo; System.out.println(com1.compare("a", "b")); } @Test public void test04() { // 构造器引用 // Supplier 中的 T get() Supplier<Object> supplier1 = new Supplier<Object>() { @Override public Object get() { return new Object(); } }; System.out.println(supplier1.get()); System.out.println("使用方法引用如下:"); Supplier<Object> supplier2 = Object::new; System.out.println(supplier2.get()); // 数组引用 // Function 中的 R apply(T t) Function<Integer, String[]> func1 = length -> new String[length]; String[] strings = func1.apply(6); System.out.println(Arrays.toString(strings)); System.out.println("使用方法引用如下:"); Function<Integer, String[]> func2 = String[] ::new; String[] strings2 = func1.apply(6); System.out.println(Arrays.toString(strings2)); } }
Java8中有两大最为重要的改变。第一个是 Lambda 表达式;另外一个则是 Stream API(java.util.stream.*)。
Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。
stream 流是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。
集合讲究的是数据,流讲究的是计算!

创建方式一:通过集合创建 Stream 流
创建方式一:通过数组创建 Stream 流
创建方式一:通过 Stream 流的静态方法 of( ) 创建
创建方式一:由函数创建流:创建无限流
/** * 通过集合创建 Stream 流 */ @Test public void createStreamByCollection() { List<String> list = Arrays.asList("aaa","bbb","ccc"); // 1.串行流 Stream<String> stream = list.stream(); // 2.并行流 Stream<String> parallelStream = list.parallelStream(); } /** * 通过数组创建 Stream 流 */ @Test public void createStreamByArray() { int[] arr = new int[]{1,2,3,4,5,6}; // 调用 Arrays 类的静态方法 stream IntStream stream = Arrays.stream(arr); } /** * 通过 Stream 流的 静态方法of() 创建 */ @Test public void createStreamByOf() { Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5); } /** * 由函数创建流:创建无限流 */ @Test public void createStream() { Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5); // 迭代 //public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) Stream.iterate(0,t -> t + 2).limit(10).forEach(System.out::println); // 生成 // public static<T> Stream<T> generate(Supplier<T> s) Stream.generate(Math::random).limit(10).forEach(System.out::println); }
public class StreamAPITest2 { /** * 筛选与切片 */ @Test public void test() { List<String> list = Arrays.asList("李华","小明","小红","小王","李华"); System.out.println(list); System.out.println("*************************"); // filter(Predicate p) 接收Lambda,从流中排除某些元素。 List<String> filterList = list.stream().filter(e -> !e.equals("李华")).collect(Collectors.toList()); System.out.println(filterList); System.out.println("*************************"); // limit(n) 截断流,使其元素不超过给定数量。 System.out.println(list.stream().limit(2).collect(Collectors.toList())); System.out.println("*************************"); // skip(n) 跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与limit()互补. System.out.println(list.stream().skip(2).collect(Collectors.toList())); System.out.println("*************************"); // distinct() 筛选,通过流所生成元素的hashCode()和equals()去除重复元素 System.out.println(list); System.out.println(list.stream().distinct().collect(Collectors.toList())); System.out.println("*************************"); } }


/** * map 与 flatMap映射 */ @Test public void testMap() { List<String> list = Arrays.asList("aa", "bb", "cc", "dd"); // map(Function f) 接收一个函数作为参数,将元素转换成其他形式或提取信息, // 该函数会被应用到每个元素上,并将其映射成一个新的元素。 // System.out.println(list.stream().map(str -> str.toUpperCase()).collect(Collectors.toList())); System.out.println(list.stream().map(String::toUpperCase).collect(Collectors.toList())); // flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。 // 未使用 flatMap Stream<Stream<Character>> streamStream = list.stream().map(StreamAPITest2::formStringToStream); streamStream.forEach(s -> { s.forEach(System.out::println); }); System.out.println("****************************"); // 使用 flatMap Stream<Character> characterStream = list.stream().flatMap(StreamAPITest2::formStringToStream); characterStream.collect(Collectors.toList()).forEach(System.out::println); } public static Stream<Character> formStringToStream(String str) { List<Character> list = new ArrayList<>(); char[] chars = str.toCharArray(); for (char c : chars) { list.add(c); } return list.stream(); }

/**
* 排序
*/
@Test
public void testSort() {
// sorted() 自然排序
List<Integer> integerList = Arrays.asList(12, 23, -12, 32, 55, 66, 11);
integerList.stream().sorted().forEach(System.out::println);
System.out.println("***************************");
// sorted(Comparator com) 定制排序
integerList.stream().sorted( (x,y) -> Integer.compare(y,x)).forEach(System.out::println);
}

/**
* 终止操作 : 归约
*/
@Test
public void testReduce() {
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
// reduce(T t, BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 T
System.out.println(integerList.stream().reduce(0, Integer::sum));
// reduce(BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 Optional<T>
// System.out.println(integerList.stream().reduce((a, b) -> a + b));
System.out.println(integerList.stream().reduce(Integer::sum));
}

/**
* 终止操作 : 收集
*/
@Test
public void testCollect() {
List<Integer> integerList = Arrays.asList(1, 2, 2, 2, 3, 4);
// toList
System.out.println(integerList.stream().skip(1).collect(Collectors.toList()));
// toSet
System.out.println(integerList.stream().skip(1).collect(Collectors.toSet()));
}

Optional 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。
Optional.of(T t) : 创建一个 Optional 实例
Optional.empty() : 创建一个空的 Optional 实例
Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则创建空实例
isPresent() : 判断是否包含值
orElse(T t) : 如果调用对象包含值,返回该值,否则返回t
orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值
map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()
flatMap(Function mapper):与 map 类似,要求返回值必须是Optional
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。