1. Lambda
1.1 Runnable
public static void main1(String[] args) {
new Thread(() -> {
System.out.println("666");
}).start();
System.out.println("777");
}
public static void main2(String[] args) {
int a = 111;
int b = 222;
new Thread(() -> {
System.out.println(calculateNum(a, b, (left, right) -> left + right));
}).start();
System.out.println(calculateNum(a, b, (left, right) -> Math.abs(left - right)));
}
1.2 IntPredicate
public static void printNumFilter(int[] arr, IntPredicate predicate) {
for (int i = 0; i < arr.length; i++) {
if(predicate.test(arr[i])) {
System.out.print(arr[i] + " ");
}
}
}
public static void main3(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
printNumFilter(arr, x -> x % 2 == 0);
}
1.3 Function
public static void main4(String[] args) {
int ret = typeConver("123456", str -> Integer.parseInt(str));
System.out.println(ret * 10);
String result = typeConver("123456", str -> str + str);
System.out.println(result);
}
public static <R> R typeConver(String str, Function<String, R> function) {
return function.apply(str);
}
1.4 IntConsumer
public static void main5(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
foreachArr(arr, x -> System.out.println(x % 2 == 0 ? (x + 2) / 2 : (x + 3) / 2));
}
public static void foreachArr(int[] arr, IntConsumer consumer) {
for(int x : arr) {
consumer.accept(x);
}
}
2. Stream
2.0 测试案例
package com.example.demo.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Author {
//id
private Long id;
//姓名
private String name;
//年龄
private Integer age;
//简介
private String intro;
//作品 I
private List<Book> books;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Author author = (Author) o;
return Objects.equals(id, author.id) && Objects.equals(name, author.name) && Objects.equals(age, author.age) && Objects.equals(intro, author.intro) && Objects.equals(books, author.books);
}
@Override
public int hashCode() {
return Objects.hash(id, name, age, intro, books);
}
public static List<Author> getAuthors() {
//数据初始化
Author author = new Author(1L, "蒙多", 33, "一个从菜刀中明悟哲理的祖安人", null);
Author author2 = new Author(2L, "亚拉索", 15, "获在风也追逐不上他的思考速度", null);
Author author3 = new Author(3L, "易", 14, "是这个世界在限制他的思维", null);
Author author4 = new Author(3L, "易", 14, "是这个世界在限制他的思维", null);
//书籍列表
List<Book> books1 = new ArrayList<>();
List<Book> books2 = new ArrayList<>();
List<Book> books3 = new ArrayList<>();
books1.add(new Book(1L, "刀的两侧是光明与黑暗", "哲学,爱清", 88, "用一把刀划分了爱恨"));
books1.add(new Book(2L, "一个人不能死在同一把刀下", "个人成长,爱情", 99, "讲述如何从失败中明悟真理"));
books2.add(new Book(3L, "那风吹不到的地方", "哲学", 85, "带你用思维去领略世界的尽头"));
books2.add(new Book(3L, "那风吹不到的地方", "哲学", 85, "带你用思维去领略世界的尽头"));
books2.add(new Book(4L, "吹或不吹", "爱情,个人传记", 56, "一个哲学家的恋爱观注定很难把他所在的时代理解"));
books3.add(new Book(5L, "你的剑就是我的剑", "爱情", 56, "无法想象一个武者能对他的伴侣这么的宽容"));
books3.add(new Book(6L, "风与剑", "个人传记", 100, "两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢?"));
books3.add(new Book(6L, "风与剑", "个人传记", 100, "两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢?"));
author.setBooks(books1);
author2.setBooks(books2);
author3.setBooks(books3);
author4.setBooks(books3);
List<Author> authorList = new ArrayList<>(Arrays.asList(author, author2, author3, author4));
return authorList;
}
}
package com.example.demo.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
@Data
@AllArgsConstructor
public class Book {
//id
private Long id;
//书名
private String name;
//分类
private String category;
//评分
private Integer score;
//简介
private String intro;
}
2.1 distinct、filter、forEach
public static void main1(String[] args) {
// System.out.println(Author.getAuthors());
List<Author> list = Author.getAuthors(); // 获取集合
Set<Author> set = new HashSet(list);
list.stream()// 获取集合的流对象
.distinct() // 去重
.filter(x -> x.getAge().compareTo(18) < 0) // 过滤
.forEach(x -> System.out.println(x)) // 终结操作
;
set.stream()// 获取集合的流对象
.distinct() // 去重
.filter(x -> x.getAge().compareTo(18) < 0) // 过滤
.forEach(x -> System.out.println(x)) // 终结操作
;
}
public static void main2(String[] args) {
Integer[] arr = {1, 2, 3, 4, 5};
Arrays.stream(arr)
.distinct()
.filter(x -> x > 2)
.forEach(x -> System.out.println(x))
;
Stream.of(arr)
.distinct()
.filter(x -> x > 2)
.forEach(x -> System.out.println(x))
;
}
public static void main3(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>(){{
this.put("555", 5);
this.put("666", 6);
this.put("777", 7);
this.put("888", 8);
this.put("999", 9);
}};
map.entrySet().stream()
.distinct()
.filter(x -> x.getValue() > 7)
.forEach(x -> System.out.println(x))
;
}
2.2 map、sorted、limit、skip、flatMap
public static void main4(String[] args) {
List<Author> list = Author.getAuthors();
list.stream()
.filter(author -> author.getName() != null && author.getName().length() > 1)
.forEach(author -> System.out.println(author));
;
System.out.println("---------------------------------------------------------------------------");
list.stream()
.map(author -> author.getName())
.distinct()
.forEach(s -> System.out.println(s));
;
System.out.println("---------------------------------------------------------------------------");
list.stream()
.map(author -> author.getAge() + 1)
.map(age -> String.valueOf(age + 10))
.map(s -> s + s + s)
.distinct()
.forEach(s -> System.out.println(s));
;
System.out.println("---------------------------------------------------------------------------");
list.stream()
.distinct()
.sorted((o1, o2) -> o2.getAge().compareTo(o1.getAge()))
.forEach(x -> System.out.println(x.getAge()))
;
System.out.println("---------------------------------------------------------------------------");
list.stream()
.distinct()
.sorted((o1, o2) -> o2.getAge().compareTo(o1.getAge()))
.map(author -> author.getName())
.limit(2)
.forEach(x -> System.out.println(x))
;
System.out.println("---------------------------------------------------------------------------");
list.stream()
.distinct()
.sorted((o1, o2) -> o2.getAge().compareTo(o1.getAge()))
.skip(1)
.forEach(x -> System.out.println(x))
;
System.out.println("---------------------------------------------------------------------------");
list.stream()
.flatMap(author -> author.getBooks().stream())
.distinct()
.forEach(x -> System.out.println(x.getName()));
;
System.out.println("---------------------------------------------------------------------------");
list.stream()
.flatMap(author -> author.getBooks().stream())
// .map(book -> book.getCategory())
.flatMap(book -> Arrays.stream(book.getCategory().split(",")))
.distinct()
.filter(s -> !s.equals("哲学"))
.filter(s -> !s.equals("爱情"))
.forEach(s -> System.out.println(s))
;
}
2.3 count、max、min、collect
public static void main5(String[] args) {
List<Author> list = Author.getAuthors();
long count = list.stream()
.flatMap(author -> author.getBooks().stream())
.distinct()
.count()
;
System.out.println(count);
System.out.println("---------------------------------------------------------------------------");
Optional<Book> max = list.stream()
.flatMap(author -> author.getBooks().stream())
.max(((o1, o2) -> o1.getScore().compareTo(o2.getScore())));
System.out.println(max.get());
Optional<Book> min = list.stream()
.flatMap(author -> author.getBooks().stream())
.min(((o1, o2) -> o1.getScore().compareTo(o2.getScore())));
System.out.println(min.get());
System.out.println("---------------------------------------------------------------------------");
List<Book> books = list.stream()
.flatMap(author -> author.getBooks().stream())
.distinct()
.collect(Collectors.toList());
System.out.println(books);
Set<Book> bookSet = list.stream()
.flatMap(author -> author.getBooks().stream())
.collect(Collectors.toSet());
System.out.println(bookSet);
Map<String, List<Book>> collect = list.stream()
.distinct()
.collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));
System.out.println(collect);
}
2.4 anyMatch、allMatch、noneMatch
public static void main6(String[] args) {
List<Author> list = Author.getAuthors();
boolean flag = list.stream()
.anyMatch(author -> author.getAge().compareTo(29) > 0);
System.out.println(flag);
flag = list.stream()
.allMatch(author -> author.getAge().compareTo(29) > 0);
System.out.println(flag);
flag = list.stream()
.noneMatch(author -> author.getAge().compareTo(100) > 0);
System.out.println(flag);
}
2.5 findAny、findFirst
public static void main7(String[] args) {
List<Author> list = Author.getAuthors();
list.stream()
.filter(author -> author.getAge().compareTo(188) > 0)
.findAny()
.ifPresent(author -> System.out.println(author));
list.stream()
.sorted((o1, o2) -> o1.getAge().compareTo(o2.getAge()))
.findFirst()
.ifPresent(author -> System.out.println(author));
List<Author> list1 = new ArrayList<>(Author.getAuthors());
// list1.add(null);
Object[] objects = list1.toArray();
if(!Arrays.stream(objects).allMatch(o -> o != null)) {
System.out.println("isnull");
}
}
2.6 reduce
public static void main8(String[] args) {
List<Author> list = Author.getAuthors();
String name = "";
Integer reduce1 = list.stream()
.map(author -> author.getAge())
.reduce(0, (x1, x2) -> x1 += x2);
System.out.println(reduce1);
List<Book> list1 = new ArrayList();
String reduce2 = list.stream()
.map(author -> author.getName())
.reduce(name, (x1, x2) -> x1 += x2);
System.out.println(name);
System.out.println(reduce2);
List<Book> reduce3 = list.stream()
.map(author -> author.getBooks())
.reduce(list1, (x1, x2) -> {
list1.addAll(x2);
return list1;
});
System.out.println(reduce3);
System.out.println(list1);
System.out.println(reduce3 == list1);
Integer reduce4 = list.stream()
.map(author -> author.getAge())
.reduce(0, (x1, x2) -> Math.max(x1, x2));
Integer reduce5 = list.stream()
.map(author -> author.getAge())
.reduce(Integer.MAX_VALUE, (x1, x2) -> Math.min(x1, x2));
System.out.println(reduce4);
System.out.println(reduce5);
}
public static void main9(String[] args) {
List<Author> list = Author.getAuthors();
list.stream()
.map(author -> author.getBooks())
.reduce((x1, x2) -> {
x1.addAll(x2);
return x1;
})
.ifPresent(books -> System.out.println(books))
;
list.stream()
.map(author -> author.getBooks())
.reduce((x1, x2) -> {
x1.addAll(x2);
return x1;
})
.ifPresent(books -> System.out.println(books))
;
}
2.7 Predicate对象的and、or、negate方法
public static void main10(String[] args) {
List<Author> authors = Author.getAuthors();
authors.stream()
.distinct()
.filter(((Predicate<Author>) author -> author.getAge().compareTo(17) > 0)
.and(author -> Optional.ofNullable(author).orElseThrow(() -> new RuntimeException("没有名字")).getName().length() > 1))
.forEach(author -> System.out.println(author));
;
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
printNumAnd(arr, x -> x % 2 == 0);
System.out.println("------------------------------------------");
printNumAnd(arr, x -> x % 2 == 0, x -> x > 5);
System.out.println("------------------------------------------");
printNumAnd(arr, x -> x % 2 == 0, x -> x > 5, x -> x < 9);
System.out.println("------------------------------------------");
printNumOr(arr, x -> x % 2 == 0);
System.out.println("------------------------------------------");
printNumOr(arr, x -> x % 2 == 0, x -> x > 5);
System.out.println("------------------------------------------");
printNumOr(arr, x -> x % 2 == 0, x -> x > 5, x -> x < 9);
System.out.println("------------------------------------------");
printNumNegate(arr, x -> x % 2 == 0);
System.out.println("------------------------------------------");
printNumNegate(arr, x -> x % 2 == 0, x -> x > 5);
System.out.println("------------------------------------------");
printNumNegate(arr, x -> x % 2 == 0, x -> x > 5, x -> x < 9);
System.out.println("------------------------------------------");
}
public static void printNumAnd(int[] arr, IntPredicate... predicates) {
IntPredicate predicate = Arrays.stream(predicates)
.reduce((x1, x2) -> x1.and(x2))
.orElse(null);
Arrays.stream(arr)
.filter(predicate)
.forEach(x -> System.out.println(x));
;
}
public static void printNumOr(int[] arr, IntPredicate... predicates) {
IntPredicate predicate = Arrays.stream(predicates)
.reduce((x1, x2) -> x1.or(x2))
.orElse(null);
Arrays.stream(arr)
.filter(predicate)
.forEach(x -> System.out.println(x));
;
}
public static void printNumNegate(int[] arr, IntPredicate... predicates) {
IntPredicate predicate = Arrays.stream(predicates)
.reduce((x1, x2) -> x1.or(x2))
.orElse(null);
Arrays.stream(arr)
.filter(predicate.negate())
.forEach(x -> System.out.println(x));
;
}
3. 引用简化
public interface UseString {
String use(String str, int start, int length);
}
public static void main11(String[] args) {
List<Author> list = Author.getAuthors();
List<String> authors = Author.getAuthors().stream().map(author -> author.getName()).collect(Collectors.toList());
list.stream()
.map(author -> author.getName())
.map(name -> String.valueOf(name))
.forEach(s -> System.out.println(s));
;
list.stream()
.map(author -> author.getName())
.map(String::valueOf)
.forEach(s -> System.out.println(s));
;
list.stream()
.map(author -> author.getName())
.forEach(name -> authors.add(name));
;
list.stream()
.map(author -> author.getName())
.forEach(authors::add);
;
list.stream()
.map(author -> author.getName())
.map(String::valueOf)
.forEach(System.out::println);
;
list.stream()
.map(Author::getName)
.forEach(authors::add);
;
list.stream()
.distinct()
.map(Author::getName)
.map(name -> subAuthorName(name, 0, 1, String::substring))
.forEach(System.out::println);
;
list.stream()
.distinct()
.map(Author::getName)
.map(name -> new StringBuilder(name))
.forEach(System.out::println);
;
list.stream()
.distinct()
.map(Author::getName)
.map(StringBuilder::new)
.forEach(System.out::println);
;
}
public static String subAuthorName(String str, int start, int length, UseString useString) {
return useString.use(str, start, length);
}
4. 基本数据类型优化
public static void main12(String[] args) {
List<Author> list = Author.getAuthors();
list.stream()
.distinct()
.mapToInt(Author::getAge)
.map(age -> age + 10)
.filter(age -> age > 18)
.map(age -> age + 2)
.forEach(System.out::println);
;
list.stream()
.distinct()
.map(Author::getAge)
.map(age -> age + 10)
.filter(age -> age > 18)
.map(age -> age + 2)
.forEach(System.out::println)
;
}
5. Optional
5.0 测试用例
public static Optional<Author> getOA() {
return Optional.ofNullable(Author.getAuthors().get(0));
}
public static Optional<Author> getNULL() {
return Optional.ofNullable(null);
}
5.1 创建Optional对象、ifPresent
public static void main1(String[] args) {
List<Author> authors = Author.getAuthors();
Optional<Author> author1 = Optional.ofNullable(authors.get(0));
Optional<Author> author2 = Optional.ofNullable(null);
author1.ifPresent(a -> System.out.println(a));
author2.ifPresent(a -> System.out.println(a));
Optional<Author> oa = getOA();
oa.ifPresent(a -> System.out.println(a));
}
5.2 filter
public static void main2(String[] args) {
getOA().filter(author -> author.getAge().compareTo(188) > 0)
.ifPresent(author -> System.out.println(author))
;
boolean present = getOA().filter(author -> author.getAge().compareTo(188) > 0).isPresent();
System.out.println(present);
}
5.3 map、flatMap
public static void main3(String[] args) {
getOA().map(author -> author.getBooks())
.ifPresent(books -> System.out.println(books));
getOA().flatMap(author -> Optional.ofNullable(author.getBooks()));
}
5.4 orElse、orElseGet、orElseThrow
public static void main4(String[] args) {
System.out.println(getOA().get());
// System.out.println(getNULL().get());
System.out.println(getNULL().orElse(new Author()));
System.out.println(getNULL().orElseGet(() -> new Author()));
System.out.println(getNULL().orElseThrow(() -> new RuntimeException("数据为null")));
}
6. 并行流
public static void main14(String[] args) {
Stream.of(1, 2, 3, 4, 5).parallel()
.peek(System.out::println)
.mapToInt(x -> x)
.filter(x -> x > 1)
.reduce((x1, x2) -> x1 += x2)
.ifPresent(System.out::println);
;
Stream.of(1, 2, 3, 4, 5).parallel()
.peek(x -> System.out.println(x + " " + Thread.currentThread().getName()))
// 区别于foreach,这个可以在中偷看调试流对象,而其他终结操作是返回值的,没有对应的peek这种的消费数据的方法
// 并且,这个不算终结方法,所以整体没有终结方法的话,这个peek也不会生效
.mapToInt(x -> x)
.filter(x -> x > 1)
.reduce((x1, x2) -> x1 += x2)
.ifPresent(System.out::println);
;
Stream.of(1, 2, 3, 4, 5).parallel()
.forEach(System.out::println);
;
}
public static void main15(String[] args) {
List<Author> list = Author.getAuthors();
Integer reduce1 = list.stream().parallel()
.map(Author::getAge)
.reduce(0, (x1, x2) -> x1 += x2);
System.out.println(reduce1);
Integer reduce2 = list.parallelStream()
.map(Author::getAge)
.reduce(0, (x1, x2) -> x1 += x2);
System.out.println(reduce2);
}
会生效
.mapToInt(x -> x)
.filter(x -> x > 1)
.reduce((x1, x2) -> x1 += x2)
.ifPresent(System.out::println);
;
Stream.of(1, 2, 3, 4, 5).parallel()
.forEach(System.out::println);
;
}
public static void main15(String[] args) {
List<Author> list = Author.getAuthors();
Integer reduce1 = list.stream().parallel()
.map(Author::getAge)
.reduce(0, (x1, x2) -> x1 += x2);
System.out.println(reduce1);
Integer reduce2 = list.parallelStream()
.map(Author::getAge)
.reduce(0, (x1, x2) -> x1 += x2);
System.out.println(reduce2);
}
7. 函数常量
有时,我们输入的函数是挺固定的,我们就可以写个变量:
private final Function<?, ?> function = Object::toString;
function
,可以看成一个函数常量
如果写成成员属性的话,这样就会导致局部变量无法出现在函数体中,所以可以这样,不局限于变量,可以封装成方法,将局部变量作为参数:
private Function<?, ?> function(String extra) {
return x -> x.toString() + extra;
}
function(extra)
,也可以看成一个函数常量
敬请期待《函数式编程深度解析》
文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆!代码:functional-programming · 游离态/马拉圈2023年11月 - 码云 - 开源中国 (gitee.com)