示例源码
示例源码
光看不练只能有个印象,自己手动写出的代码,才能加深学习深度。拿出你的小手敲出自己的示例代码。
lamda表达式
java的语法糖,本质是匿名内部类
- 示例
public class LambdaDemo01 {
public static void main(String[] args) {
// 匿名内部类方式
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello Runnable...");
}
}).start();
// lambda方式
new Thread(() -> {
System.out.println("Hello Runnable lambda...");
}).start();
}
}
public class LambdaDemo02 {
public static void main(String[] args) {
// 匿名内部类实现加法操作
System.out.println(operator(10, 20, new IntBinaryOperator() {
@Override
public int applyAsInt(int left, int right) {
return left + right;
}
}));
// lambda实现加法操作
System.out.println(operator(10, 20, (a, b) -> {
return a + b;
}));
// 继续简化
System.out.println(operator(10, 20, (a, b) -> a + b ));
}
/**
* 定义一个操作方法
*
* @param a
* @param b
* @param operator
* @return
*/
public static int operator(int a, int b, IntBinaryOperator operator) {
return operator.applyAsInt(a, b);
}
}
public class LambdaDemo03 {
public static void main(String[] args) {
// 偶数才打印
testPrint(value -> value % 2 == 0);
}
/**
* 定义一个操作方法
*
* @param intPredicate
* @return
*/
public static void testPrint(IntPredicate intPredicate) {
for (int i = 0; i < 10; i++) {
if (intPredicate.test(i)) {
System.out.println(i);
}
}
}
}
public static void main(String[] args) {
// 将字符串转Integer
System.out.println(typeConvert((Function<String, Integer>) s -> Integer.valueOf(s), "10"));
}
/**
* 类型转换,将T转换成R
*
* @param fun
* @return
*/
public static <T, R> R typeConvert(Function<T, R> fun, T src) {
return fun.apply(src);
}
public class LambdaDemo05 {
public static void main(String[] args) {
myConsumer(value -> System.out.println(value));
}
public static void myConsumer(IntConsumer intConsumer) {
for (int i = 0; i < 10; i++) {
intConsumer.accept(i);
}
}
}
Stream 流
java8 利用函数式编程,对集合或数组进行流式操作的类库
- 惰性求值(没有终结操作,中间操作是不会被执行的)
- 流是一次性的(流终结操作后,不能继续被使用)
- 不会影响原数据(对集合元素的属性做set处理是会设置到原集合的)
public class StreamDemo01 {
public static void main(String[] args) {
List<Author> authors = MyUtil.getAuthorList();
// 去重并打印年龄小于25的作者名称
authors.stream().distinct().filter(author -> author.getAge() < 25).forEach(author -> System.out.println(author.getName()));
}
}
创建流
public class StreamDemo02 {
public static void main(String[] args) {
// 创建流的方式
// list
List<Author> authors = MyUtil.getAuthorList();
Stream<Author> stream = authors.stream();
// 数组
String[] arr = new String[1];
Stream<String> stream1 = Arrays.stream(arr);
Stream<String> arr1 = Stream.of(arr);
// map
Map<String, String> map = new HashMap<>();
Stream stream2 = map.entrySet().stream();
}
}
中间操作
返回流对象的方法,必须调用终结操作,中间操作才会执行
- filter 过滤
- map
- distinct 去重
- sorted 排序
- limit 截取长度
- skip 跳过
- flagMap
public class StreamDemo03 {
public static void main(String[] args) {
List<Author> authors = MyUtil.getAuthorList();
authors.stream()
// 获取书籍的流
.flatMap((Function<Author, Stream<Book>>) author -> author.getBooks().stream())
.forEach(book -> System.out.println(book.getName()));
authors.stream()
// 一个作者搞成两个
.flatMap((Function<Author, Stream<Author>>) author -> Stream.of(new Author[]{author, author}))
.forEach(author -> System.out.println(author.getName()));
}
}
终结操作
不返回流对象的方法,必须调用终结操作,中间操作才会执行
- forEach
- count
- min/max
public class StreamDemo04 {
public static void main(String[] args) {
List<Author> authors = MyUtil.getAuthorList();
// 计数
System.out.println(authors.stream().count());
// 最大年龄
System.out.println(authors.stream().max(Comparator.comparingInt(Author::getAge)).get().getAge());
// 最小年龄
System.out.println(authors.stream().min(Comparator.comparingInt(Author::getAge)).get().getAge());
}
}
- collect 把当前流转成集合
public class StreamDemo05 {
public static void main(String[] args) {
List<Author> authors = MyUtil.getAuthorList();
// collect 转回list
List<String> list = authors.stream().map(author -> author.getName()).collect(Collectors.toList());
System.out.println(list);
// collect 转回set
Set<String> set = authors.stream().map(author -> author.getName()).collect(Collectors.toSet());
System.out.println(set);
// collect 转回map
Map<String, Integer> map = authors.stream().collect(Collectors.toMap(author -> author.getName(), author -> author.getAge()));
System.out.println(map);
}
}
- anyMatch
- allMatch
- noneMatch
public class StreamDemo06 {
public static void main(String[] args) {
List<Author> authors = MyUtil.getAuthorList();
// 集合中匹配任何一个都返回true
boolean anyMatch = authors.stream().anyMatch(author -> author.getAge() > 10);
System.out.println(anyMatch);
// 集合中全部匹配才返回true
boolean allMatch = authors.stream().allMatch(author -> author.getAge() > 30);
System.out.println(allMatch);
// 集合中全部不匹配才返回true
boolean noneMatch = authors.stream().noneMatch(author -> author.getAge() > 130);
System.out.println(noneMatch);
}
}
- findAny
- findFirst
public class StreamDemo07 {
public static void main(String[] args) {
List<Author> authors = MyUtil.getAuthorList();
// 返回集合中的一个
Optional<Author> any = authors.stream().findAny();
any.ifPresent(author -> System.out.println(author.getName()));
// 查找第一个
authors.stream().findFirst().ifPresent(author -> System.out.println(author.getName()));
}
}
- reduce
public class StreamDemo08 {
public static void main(String[] args) {
List<Author> authors = MyUtil.getAuthorList();
// reduce 示例 查找年龄最大的
authors.stream().reduce((author, author2) -> author.getAge() > author2.getAge() ? author : author2).ifPresent(author -> System.out.println(author.getAge()));
// reduce 示例 查找年龄最小的
authors.stream().reduce((author, author2) -> author.getAge() < author2.getAge() ? author : author2).ifPresent(author -> System.out.println(author.getAge()));
// reduce 示例 计算年龄合计
System.out.println(authors.stream().map(author -> author.getAge()).reduce(0, (result, age) -> result + age));
System.out.println(authors.stream().reduce(new Author(0, 0, "", null), (author, author2) -> {
author.setAge(author.getAge() + author2.getAge());
return author;
}).getAge());
}
}
并行流
public class StreamDemo09 {
public static void main(String[] args) {
List<Author> authors = MyUtil.getAuthorList();
// 创建并行流1 stream().parallel()
authors.stream().parallel().reduce((author, author2) -> author.getAge() > author2.getAge() ? author : author2).ifPresent(author -> System.out.println(author.getAge()));
// 创建并行流2 parallelStream()
authors.parallelStream().reduce((author, author2) -> author.getAge() < author2.getAge() ? author : author2).ifPresent(author -> System.out.println(author.getAge()));
}
}
Optional
创建对象
public class OptionalDemo01 {
public static void main(String[] args) {
Author author = new Author();
// ofNullable 可以为空
Optional<Author> authorOptional1 = Optional.ofNullable(author);
// of 不能为空,将报空指针
Optional<Author> authorOptional2 = Optional.of(author);
// empty 创建一个空对象的
Optional<Object> empty = Optional.empty();
}
}
获取值
public class OptionalDemo02 {
public static void main(String[] args) {
Author authorNull = null;
Author author = new Author(1, 28, "东山", null);
Optional<Author> authorNullOptional = Optional.ofNullable(authorNull);
Optional<Author> authorOptional = Optional.ofNullable(author);
// get
// 东山
System.out.println(authorOptional.get().getName());
// orElseGet 为空将返回默认值 否则使用原值
// 默认
System.out.println(authorNullOptional.orElseGet(() -> new Author(0, 0, "默认", null)).getName());
// 东山
System.out.println(authorOptional.orElseGet(() -> new Author(0, 0, "默认", null)).getName());
// orElseThrow 为空抛出异常
authorNullOptional.orElseThrow(() -> new RuntimeException("数据不能为空")) ;
}
}
过滤&判断&数据转换
public class OptionalDemo03 {
public static void main(String[] args) {
Author author = new Author(1, 28, "东山", null);
Optional<Author> authorOptional = Optional.ofNullable(author);
// filter 过滤 // 没得打印
authorOptional.filter(author1 -> author1.getAge() > 28).ifPresent(author12 -> System.out.println(author12.getName()));
// filter 过滤 // 打印东山
authorOptional.filter(author1 -> author1.getAge() > 18).ifPresent(author12 -> System.out.println(author12.getName()));
// isPresent 判断 // 打印东山
if (authorOptional.isPresent()) {
System.out.println(authorOptional.get().getName());
}
// map 数据转换 转成年龄 // 打印28
System.out.println(authorOptional.map(author13 -> author13.getAge()).get());
}
}
函数式接口
只有一个抽象方法的接口
一般加上@FunctionalInterface,不加该注解,也可以是函数式接口
常用接口
Consumer 消费接口
Function 转换接口
Predicate 判断接口
Supplier 生产接口
默认方法
public class FunctionDemo01 {
public static void main(String[] args) {
List<Author> authors = MyUtil.getAuthorList();
// and
authors.stream().filter(((Predicate<Author>) author -> author.getAge() > 11).and(author -> author.getAge() < 33)).forEach(author -> System.out.println(author.getName()));
System.out.println("------------------------");
// or
authors.stream().filter(((Predicate<Author>) author -> author.getAge() > 11).or(author -> author.getAge() < 33)).forEach(author -> System.out.println(author.getName()));
System.out.println("------------------------");
// negate
authors.stream().filter(((Predicate<Author>) author -> author.getAge() > 33).negate()).forEach(author -> System.out.println(author.getName()));
}
}
方法引用
当我们使用lambda时,当方法体中只有一个方法调用的话,我们可以用方法引用进一步简化代码
- 当我们写完lambda代码后,发现方法体中只有一个方法调用的话,再使用idea提供的快捷键来尝试方法引用
- 用法:类名或对象名::方法名
示例
- 引用类的静态方法
- 引用对象的实例方法
- 引用类的实例方法
public class FunctionDemo02 {
public static void main(String[] args) {
List<Author> authors = MyUtil.getAuthorList();
final StringBuilder sb = new StringBuilder() ;
// lambda 写法
authors.stream().map(author -> author.getAge()).map(integer -> String.valueOf(integer)).forEach(s -> sb.append(s));
System.out.println(sb.toString());
final StringBuilder sb1 = new StringBuilder() ;
// 方法引用写法
// 引用类的实例方法 Author::getAge 满足方法体重只有一个方法调用,并且是第一个参数的实例方法,并且该方法按照顺序传入的抽象方法中的剩余参数(此处没有剩余参数)
// 引用类的静态方法 String::valueOf 满足方法体中只有一个方法调用,并且是静态方法,抽象方法所有参数按照顺序传入静态方法
// 引用对象的实例方法 sb::append 满足方法体中只有一个方法调用,并且是对象的实例方法,抽象方法所有参数按照顺序传入实例方法
authors.stream().map(Author::getAge).map(String::valueOf).forEach(sb1::append);
System.out.println(sb1.toString());
}
}
- 构造器引用
public class FunctionDemo03 {
public static void main(String[] args) {
List<Author> authors = MyUtil.getAuthorList();
// lambda 写法
authors.stream().map(author -> author.getName()).map(name -> new String(name)) ;
// 方法引用写法
// 构造器引用 String::new 满足方法体只有一个构造方法调用,并且抽象方法的所有参数都按照顺序传入该方法
authors.stream().map(Author::getName).map(String::new) ;
}
}