Java8新特性Lambda表达式
AI-摘要
Zpeng GPT
AI初始化中...
介绍自己
生成本文简介
推荐相关文章
前往主页
前往tianli博客
本文最后更新于 2024-04-01,欢迎来到我的Blog! https://www.zpeng.site/
Java8新特性Lambda表达式
1.介绍
Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包,和传统数学上的意义有区别。
Java8引入了一个新的操作符: ->,该操作符称为箭头操作符或Lambda操作符,箭头操作符将Lambda表达式拆分为2部分
左侧:Lambda表达式的参数列表
右侧:Lambda表达式中所执行的功能,即Lambda体
2.语法格式
左侧:表达式的参数列表(接口中方法的参数列表)
右侧:接口中方法的实现
package com.example.useragent.demos.web.Lambda;
import java.util.Comparator;
import java.util.function.Consumer;
public class TestLambda {
public static void main(String[] args) {
//语法格式1:无参无返回值
//() -> System.out.println("Hello Lambda!");
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello World!");
}
};
r1.run();
Runnable r2 = () -> System.out.println("Hello Lambda!");
r2.run();
System.out.println("--------------------------");
//语法格式2:一个参数无返回值
//(x) -> System.out.println(x)
Consumer<String> con = (x) -> System.out.println(x);
con.accept("Hello Consumer1");
// 只有一个参数,参数的小括号可以省略
Consumer<String> consumer = x -> System.out.println(x);
consumer.accept("Hello Consumer2");
System.out.println("--------------------------");
//语法格式3:有两个参数,并且lambda 体中有多条语句,并且有返回值
Comparator<Integer> com1 = (x, y) -> {
System.out.println("函数式接口");
return Integer.compare(x, y);
};
System.out.println(com1.compare(2, 4));
System.out.println("--------------------------");
//语法格式4:有两个以上参数,有返回值,若 lambda 体中只有一条语句,return和大括号都可以省略不写
Comparator<Integer> com2 = (Integer x, Integer y) -> Integer.compare(x, y);
System.out.println(com2.compare(4, 2));
// 表达式的参数列表的数据类型可以省略不写,因为JVM可以通过上下文推断出数据类型,即“类型推断”
Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
System.out.println(com.compare(4, 2));
System.out.println("--------------------------");
}
}
3.函数式接口
只包含一个抽象方法的接口,就称为函数式接口。我们可以通过 lambda表达式来创建该接口的实现对象。我们可以在任意函数式接口上使用 @FunctionalInterface 注解,这样做可以用于检测它是否是一个函数式接口,同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口。
package com.example.useragent.demos.web.Lambda;
//们可以在任意函数式接口上使用 @FunctionalInterface 注解,这样做可以用于检测它是否是一个函数式接口
@FunctionalInterface
public interface MyFun {
public Integer getValue(Integer num);
}
package com.example.useragent.demos.web.Lambda;
public class TestLambda {
public static void main(String[] args) {
Integer num = operation(100, (x) -> x + 88);
System.out.println(num);
MyFun myfun = (x) -> x + 88;
System.out.println(myfun.getValue(100));
}
public static Integer operation(Integer num, MyFun mf) {
return mf.getValue(num);
}
}
4.内置函数式接口
Consumer<T>
:消费型接口void accept(T t);
Supplier<T>
:供给型接口T get();
Function(T,R)
:函数型接口R apply(T t);
Predicate<T>
:断言型接口boolean test(T t);
4.1Consumer<T>消费型接口
接口
package java.util.function;
import java.util.Objects;
/**
* Represents an operation that accepts a single input argument and returns no
* result. Unlike most other functional interfaces, {@code Consumer} is expected
* to operate via side-effects.
*
* <p>This is a <a href="package-summary.html">functional interface</a>
* whose functional method is {@link #accept(Object)}.
*
* @param <T> the type of the input to the operation
*
* @since 1.8
*/
@FunctionalInterface
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
测试
@Test
void test1() {
happy(1000,(X)-> System.out.println("消费了1000元!"));
}
public void happy(double money, Consumer con){
con.accept(money);
}
结果
4.2Supplier<T>供给型接口
接口
package java.util.function;
/**
* Represents a supplier of results.
*
* <p>There is no requirement that a new or distinct result be returned each
* time the supplier is invoked.
*
* <p>This is a <a href="package-summary.html">functional interface</a>
* whose functional method is {@link #get()}.
*
* @param <T> the type of results supplied by this supplier
*
* @since 1.8
*/
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
测试
/**
* 产生指定的整数集合放到集合中
* Iterable接口的forEach方法的定义:方法中使用到了Consumer消费型接口,
* default void forEach(Consumer<? super T> action) {
* Objects.requireNonNull(action);
* for (T t : this) {
* action.accept(t);
* }
* }
*/
@Test
public void test2() {
List list = addNumInList(10, () -> (int) (Math.random() * 100));
list.forEach(t -> System.out.println(t));
}
public List addNumInList(int size, Supplier<Integer> supplier) {
List<Integer> list = new ArrayList();
for (int i = 0; i < size; i++) {
list.add(supplier.get());
}
return list;
}
结果
4.3Function<T, R>函数型接口
接口
package java.util.function;
import java.util.Objects;
/**
* Represents a function that accepts one argument and produces a result.
*
* <p>This is a <a href="package-summary.html">functional interface</a>
* whose functional method is {@link #apply(Object)}.
*
* @param <T> the type of the input to the function
* @param <R> the type of the result of the function
*
* @since 1.8
*/
@FunctionalInterface
public interface Function<T, R> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
测试
/**
* 使用函数式接口处理字符串。
*/
@Test
public void test3() {
System.out.println(handleStr("abc", (String s) -> s.toUpperCase()));
}
public String handleStr(String s, Function<String, String> f) {
return f.apply(s);
}
结果
4.4Predicate<T>断言型接口
接口
package java.util.function;
import java.util.Objects;
/**
* Represents a predicate (boolean-valued function) of one argument.
*
* <p>This is a <a href="package-summary.html">functional interface</a>
* whose functional method is {@link #test(Object)}.
*
* @param <T> the type of the input to the predicate
*
* @since 1.8
*/
@FunctionalInterface
public interface Predicate<T> {
/**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
@SuppressWarnings("unchecked")
static <T> Predicate<T> not(Predicate<? super T> target) {
Objects.requireNonNull(target);
return (Predicate<T>)target.negate();
}
}
测试
/**
* 自定义条件过滤字符串集合
*/
@Test
public void test4() {
List<String> strings = Arrays.asList("啊", "23", "666", "7777","88888");
List<String> stringList1 = filterStr(strings, (s) -> s.length() > 3);
for (String s : stringList1) {
System.out.println(s);
}
}
public List<String> filterStr(List<String> list, Predicate<String> predicate) {
ArrayList result = new ArrayList();
for (int i = 0; i < list.size(); i++) {
if (predicate.test(list.get(i))) {
result.add(list.get(i));
}
}
return result;
}
结果
5.例子
//1. 使用Lambda表达式进行集合遍历
//未使用Lambda表达式:
List<String> list = Arrays.asList("apple", "banana", "orange");
for (String fruit : list) {
System.out.println(fruit);
}
//使用Lambda表达式:
List<String> list = Arrays.asList("apple", "banana", "orange");
list.forEach(fruit -> System.out.println(fruit));
//2. 使用Lambda表达式进行排序
//未使用Lambda表达式:
List<String> list = Arrays.asList("apple", "banana", "orange");
Collections.sort(list, new Comparator<String>() {
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
});
//使用Lambda表达式:
List<String> list = Arrays.asList("apple", "banana", "orange");
Collections.sort(list, (s1, s2) -> s1.compareTo(s2));
//3. 使用Lambda表达式进行过滤
//未使用Lambda表达式:
List<String> list = Arrays.asList("apple", "banana", "orange");
List<String> filteredList = new ArrayList<String>();
for (String fruit : list) {
if (fruit.startsWith("a")) {
filteredList.add(fruit);
}
}
//使用Lambda表达式:
List<String> list = Arrays.asList("apple", "banana", "orange");
List<String> filteredList = list.stream().filter(fruit -> fruit.startsWith("a")).collect(Collectors.toList());
//4. 使用Lambda表达式进行映射
//未使用Lambda表达式:
List<String> list = Arrays.asList("apple", "banana", "orange");
List<Integer> lengths = new ArrayList<Integer>();
for (String fruit : list) {
lengths.add(fruit.length());
}
//使用Lambda表达式:
List<String> list = Arrays.asList("apple", "banana", "orange");
List<Integer> lengths = list.stream().map(fruit -> fruit.length()).collect(Collectors.toList());
//5. 使用Lambda表达式进行归约
//未使用Lambda表达式:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int sum = 0;
for (int i : list) {
sum += i;
}
//使用Lambda表达式:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int sum = list.stream().reduce(0, (a, b) -> a + b);
//6. 使用Lambda表达式进行分组
//未使用Lambda表达式:
List<String> list = Arrays.asList("apple", "banana", "orange");
Map<Integer, List<String>> grouped = new HashMap<Integer, List<String>>();
for (String fruit : list) {
int length = fruit.length();
if (!grouped.containsKey(length)) {
grouped.put(length, new ArrayList<String>());
}
grouped.get(length).add(fruit);
}
//使用Lambda表达式:
List<String> list = Arrays.asList("apple", "banana", "orange");
Map<Integer, List<String>> grouped = list.stream().collect(Collectors.groupingBy(fruit -> fruit.length()));
//7. 使用Lambda表达式进行函数式接口的实现
//未使用Lambda表达式:
public interface MyInterface {
public void doSomething(String input);
}
MyInterface myObject = new MyInterface() {
public void doSomething(String input) {
System.out.println(input);
}
};
myObject.doSomething("Hello World");
//使用Lambda表达式:
MyInterface myObject = input -> System.out.println(input);
myObject.doSomething("Hello World");
//8. 使用Lambda表达式进行线程的创建
//未使用Lambda表达式:
Thread thread = new Thread(new Runnable() {
public void run() {
System.out.println("Thread is running.");
}
});
thread.start();
//使用Lambda表达式:
Thread thread = new Thread(() -> System.out.println("Thread is running."));
thread.start();
//9. 使用Lambda表达式进行Optional的操作
//未使用Lambda表达式:
String str = "Hello World";
if (str != null) {
System.out.println(str.toUpperCase());
}
//使用Lambda表达式:
Optional<String> str = Optional.ofNullable("Hello World");
str.map(String::toUpperCase).ifPresent(System.out::println);
//10. 使用Lambda表达式进行Stream的流水线操作
//未使用Lambda表达式:
List<String> list = Arrays.asList("apple", "banana", "orange");
List<String> filteredList = new ArrayList<String>();
for (String fruit : list) {
if (fruit.startsWith("a")) {
filteredList.add(fruit.toUpperCase());
}
}
Collections.sort(filteredList);
//使用Lambda表达式:
List<String> list = Arrays.asList("apple", "banana", "orange");
List<String> filteredList = list.stream().filter(fruit -> fruit.startsWith("a")).map(String::toUpperCase).sorted()
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 zpeng
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果