项目中有很多重复性的代码,都被我改成了公共泛型方法,但是关于泛型与函数编程的结合还是感觉有些吃力,所以写了些练习demo
package com.example.testdemo.entity;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.*;
import java.util.function.*;
/**
* TODO:
*
* @author WKQ
* @date 2024/4/20
*/
@Data
@Accessors(chain = true)
class Dog {
/**
* 年龄
*/
private Integer age;
/**
* 姓名
*/
private String name;
/**
* 描述:年龄大于等于8即为成年
*/
private String desc;
}
@Data
@Accessors(chain = true)
class Cat {
/**
* 年龄
*/
private Integer age;
/**
* 姓名
*/
private String name;
/**
* 描述:年龄大于等于6即为成年
*/
private String desc;
}
public class TestContent {
public static void main(String[] args) {
test1();
test2();
test3();
}
/**
* 案例1
*/
private static void test1() {
// 创建两只狗
Dog dog1 = new Dog().setAge(6).setName("小黑狗");
Dog dog2 = new Dog().setAge(8).setName("小白狗");
// 创建一个 Map,键为 Dog 对象,值为处理 Dog 对象的 Consumer
Map<Dog, Consumer<Dog>> map = new LinkedHashMap<>();
// 创建 Consumer,用于打印 Dog 的名字
Consumer<Dog> nameField = (Dog dog) -> System.out.println(dog.getName());
// 创建 Consumer,用于打印 Dog 的年龄
Consumer<Dog> ageField = (Dog dog) -> System.out.println(dog.getAge());
// 将 Consumer 添加到 Map 中
map.put(dog1, nameField);
map.put(dog2, ageField);
// 执行 Map 中的 Consumer,处理每只狗
execField(map);
// 创建两只猫
Cat cat1 = new Cat().setAge(8).setName("小白猫");
Cat cat2 = new Cat().setAge(8).setName("小黑猫");
// 创建一个 Map,键为 Cat 对象,值为处理 Cat 对象的 Consumer
Map<Cat, Consumer<Cat>> map1 = new LinkedHashMap<>();
// 创建 Consumer,用于打印 Cat 的名字
Consumer<Cat> nameField1 = (Cat cat) -> System.out.println(cat.getName());
// 创建 Consumer,用于打印 Cat 的年龄
Consumer<Cat> ageField1 = (Cat cat) -> System.out.println(cat.getAge());
// 将 Consumer 添加到 Map 中
map1.put(cat1, nameField1);
map1.put(cat2, ageField1);
// 执行 Map 中的 Consumer,处理每只猫
execField(map1);
}
/**
* 案例1
*/
private static void test2() {
// 创建三只狗
Dog dog1 = new Dog().setAge(6).setName("小黑");
Dog dog2 = new Dog().setAge(8).setName("小白");
Dog dog3 = new Dog().setAge(10).setName("小红");
// 创建一个 Map,键为 Dog 对象,值为处理 Dog 对象的 Consumer
Map<Dog, Consumer<Dog>> map = new LinkedHashMap<>();
// 创建 Consumer,用于处理 Dog 的描述(成年/未成年)
Consumer<Dog> func = (Dog dog) -> {
// 假设狗八岁成年
Predicate<Integer> judge = (Integer num) -> num >= 8;
if (judge.test(dog.getAge())) {
dog.setDesc("成年");
} else {
dog.setDesc("未成年");
}
};
// 将 Consumer 添加到 Map 中
map.put(dog1, func);
map.put(dog2, func);
map.put(dog3, func);
// 执行 Map 中的 Consumer,处理每只狗
execField(map);
}
private static void test3() {
// 创建三只狗
Dog dog1 = new Dog().setAge(6).setName("小黑狗");
Dog dog2 = new Dog().setAge(8).setName("小白狗");
Dog dog3 = new Dog().setAge(9).setName("小红狗");
// 创建一个 Map,键为 Dog 对象,值为处理 Dog 对象的 BiConsumer
Map<Dog, BiConsumer<Dog, Predicate<Integer>>> map = new LinkedHashMap<>();
// 创建 BiConsumer,用于处理 Dog 的描述(成年/未成年)
BiConsumer<Dog, Predicate<Integer>> func = (Dog dog, Predicate<Integer> judge) -> {
// 假设狗八岁成年
if (judge.test(dog.getAge())) {
dog.setDesc("成年");
} else {
dog.setDesc("未成年");
}
};
// 将 BiConsumer 添加到 Map 中
map.put(dog1, func);
map.put(dog2, func);
map.put(dog3, func);
// 执行 Map 中的 BiConsumer,处理每只狗
execField2(map, (Integer num) -> num >= 8);
// 创建三只猫
Cat cat1 = new Cat().setAge(6).setName("小黑猫");
Cat cat2 = new Cat().setAge(8).setName("小白猫");
Cat cat3 = new Cat().setAge(7).setName("小红猫");
// 创建一个 Map,键为 Cat 对象,值为处理 Cat 对象的 BiConsumer
Map<Cat, BiConsumer<Cat, Predicate<Integer>>> map2 = new LinkedHashMap<>();
// 创建 BiConsumer,用于处理 Cat 的描述(成年/未成年)
BiConsumer<Cat, Predicate<Integer>> func2 = (Cat cat, Predicate<Integer> judge) -> {
// 假设猫六岁成年
if (judge.test(cat.getAge())) {
cat.setDesc("成年");
} else {
cat.setDesc("未成年");
}
};
// 将 BiConsumer 添加到 Map 中
map2.put(cat1, func2);
map2.put(cat2, func2);
map2.put(cat3, func2);
// 执行 Map 中的 BiConsumer,处理每只猫
execField2(map2, (Integer num) -> num >= 6);
}
/**
* 执行 Map 中每个键对应的 Consumer 函数的处理逻辑。
* <p>
* 此方法遍历给定的 Map,对于每一个键值对,它获取对应的 Consumer,
* 并使用该 Consumer 对键进行处理。
*
* @param <T> 键的类型
* @param map 要处理的 Map,键为任何类型 T,值为处理该键的 Consumer<T>
*/
public static <T> void execField(Map<T, Consumer<T>> map) {
for (T t : map.keySet()) {
Consumer<T> r = map.get(t);
r.accept(t);
System.out.println(t);
}
}
/**
* 执行 Map 中每个键对应的 BiConsumer 函数的处理逻辑。
* <p>
* 此方法遍历给定的 Map,对于每一个键值对,它获取对应的 BiConsumer,
* 并使用该 BiConsumer 对键进行处理。处理时会使用提供的 Predicate 判断条件。
*
* @param <T> 键的类型
* @param map 要处理的 Map,键为任何类型 T,值为处理该键的 BiConsumer<T, Predicate<Integer>>
* @param test 用于判断的 Predicate<Integer>,用于 BiConsumer 中的判断逻辑
*/
public static <T> void execField2(Map<T, BiConsumer<T, Predicate<Integer>>> map, Predicate<Integer> test) {
for (T t : map.keySet()) {
BiConsumer<T, Predicate<Integer>> con = map.get(t);
con.accept(t, test);
System.out.println(t);
}
}
}