自定义lambda用法
基础用法
supplier
提供者: 无中生有 ()->结果
public static void main(String[] args) {
demo1(() -> "abc");
}
public static <T> void demo1(Supplier<T> tSupplier) {
T t = tSupplier.get();
System.out.println("已获取参数 >>> " + t);
}
function
函数: 一个参数一个结果 (参数)->结果, BiFunction (参数1,参数2)->结果
public static void main(String[] args) {
List<String> list = Arrays.asList("tom", "jack", "ben");
// 使用 String::toUpperCase 作为 Function ,将名字转换为大写形式
List<String> upperList = demo2(list, String::toUpperCase);
System.out.println(upperList);
// 使用 String::length 作为 Function ,将名字转换为长度
List<Integer> lengthList = demo2(list, String::length);
System.out.println(lengthList);
}
// 使用 Function<T, R> 作为参数,通过传递不同的 Function 实现来实现不同的转换操作。
public static <T, R> List<R> demo2(List<T> list, Function<T, R> function) {
// List<R> collect = list.stream().map(function::apply).collect(Collectors.toList());
return list
.stream()
.map(function) // 方法引用
.collect(Collectors.toList());
}
/**
* [TOM, JACK, BEN]
* [3, 4, 3]
*/
consumer
消费者 一个参数没结果 (参数)->void, BiConsumer (参数1,参数2)->void
public static void main(String[] args) {
List<String> list = Arrays.asList("tom", "jack", "ben");
// 打印列表
demo3(list, System.out::println);
// 转为大写后打印
demo3(list, item -> System.out.println(item.toUpperCase()));
}
public static <T> void demo3(List<T> list, Consumer<T> consumer) {
list.forEach(consumer);
}
多线程下的ABA问题以及juc包的使用(lambda设计)
public static void main(String[] args) {
demo(
() -> new int[10],
(array) -> array.length,
(array, index) -> array[index]++,
array -> System.out.println(Arrays.toString(array))
);
demo(
() -> new AtomicIntegerArray(10),
(array) -> array.length(),
(array, index) -> array.getAndIncrement(index),
array -> System.out.println(array)
);
}
private static <T> void demo(
Supplier<T> arraySupplier,
Function<T, Integer> lengthFun,
BiConsumer<T, Integer> putConsumer,
Consumer<T> printConsumer) {
List<Thread> ts = new ArrayList<>();
// 数组
T array = arraySupplier.get();
// 数组长度 l
int length = lengthFun.apply(array);
// 定义l个线程
for (int i = 0; i < length; i++) {
ts.add(new Thread(() -> {
// 每个线程对数组作 10000 次操作
for (int j = 0; j < 10000; j++) {
/*
* [0, 0, 0, 0, 0, ...] 对数组中每个数进行遍历, 并只对其中一个进行累加, 执行10000次
* 说明: 在理想条件下, 每个线程可以累加降数组中每个元素累加至1000, 10个线程可将数组中每个元素累加至10000
* 但是普通的 ++ 操作非原子性, 线程不安全, 无法累加到1000
* 因此此处需要使用 AtomicIntegerArray 原子类
*/
putConsumer.accept(array, j % length);
}
}));
}
ts.forEach(Thread::start); // 启动所有线程
ts.forEach(t -> {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}); // 等所有线程结束
printConsumer.accept(array);
}