网站Logo GESONG

lambda

gesong
13
2025-06-05

lambda表达式

算子

sorted

多条件依次排序

list=list.stream()

                //第一个排序条件

                //假设自定义对象为Obj,则可直接写为Obj::getName,sorted默认升序

                .sorted(Comparator.comparing(Application::getName)

                        //第二个排序条件(可一直延伸)

                        .thenComparing(Application::getAge).reversed()).collect(Collectors.toList());

直接.reversed()会将之前的排序结果全部倒叙,如果只是某个条件倒叙,可以加一个参数Comparator.reverseOrder();

Comparator.comparing()方法参数中最好声明类型,否则可能报错:

groupingBy

  • 分组后取一个属性

Stream流使用groupingBy+mapping实现对分组之后的对象集合转化为对象的某个属性的集合

Map<String, List<Long>> approvalNumberIdMap = goodsManuals.parallelStream().collect(Collectors.groupingBy(GoodsManual::getApprovalNumber, Collectors.mapping(GoodsManual::getId, Collectors.toList())));
  • 多字段分组成嵌套map

User user1 = new User("zhangsan", "beijing", 10);
User user2 = new User("zhangsan", "beijing", 20);
User user3 = new User("lisi", "shanghai", 30);
List<User> list = new ArrayList<User>();
list.add(user1);
list.add(user2);
list.add(user3);
Map<String, Map<String, List<User>>> collect
        = list.stream().collect(
                Collectors.groupingBy(
                        User::getAddress, Collectors.groupingBy(User::getName)
                )
);
System.out.println(collect);

collector

  • 自定义collector

例1:将stream中所有用户的用户名变成大写并用"|"符号连接成一个字符串。为了达成这个目标我们通过Collector.of()方法创建了一个新的collector,我们必须给这个collector提供四种功能:supplier, accumulator, combiner,finisher.

Collector<Person, StringJoiner, String> personNameCollector =
    Collector.of(
        () -> new StringJoiner(" | "),          // supplier
        (j, p) -> j.add(p.name.toUpperCase()),  // accumulator
        (j1, j2) -> j1.merge(j2),               // combiner
        StringJoiner::toString);                // finisher

String names = persons
    .stream()
    .collect(personNameCollector);

System.out.println(names);  // MAX | PETER | PAMELA | DAVID

例2:分组后的list转成json

                    Map<String, Map<String, String>> stringMapMap = models.parallelStream().collect(Collectors.groupingBy(e -> {
                        try {
                            return readMethod1.invoke(e).toString();
                        } catch (Exception ex) {
                            log.debug("执行getter方法失败!field: {}", field1.getName());
                        }
                        return null;
                    }, Collectors.groupingBy(e -> {
                        try {
                            return field2.getName() + readMethod2.invoke(e).toString();
                        } catch (Exception ex) {
                            log.debug("执行getter方法失败!field: {}", field2.getName());
                        }
                        return null;
                    }, Collector.of(
                            () -> new ArrayList<String>(),          // supplier
                            (j, p) -> j.add(JSON.toJSONString(p)),  // accumulator
                            (j1, j2) -> {
                                j1.addAll(j2);
                                return j1;
                            },               // combiner
                            ArrayList::toString
                    ))));

函数式接口

必看:深入学习Java8中的函数式接口

  • 四大内置核心函数式接口

    • 消费型接口 Consumer<T>

      抽象方法:void accept(T t):接收一个参数进行消费,但无需返回结果。

    • 供给型接口 Supplier<T>

      抽象方法:T get():返回一个自定义数据.

    • 函数型接口 Function<T,R>

      抽象方法:R apply(T t):传入一个参数,返回想要的结果。

    • 断言型接口 Predicate<T>

      抽象方法:boolean test(T t):传入一个参数,返回一个布尔值.

示例代码:lambda表达式就是抽象方法的实现

public class Test {
    public static void main(String[] args) {
        String s = test_supplier(() -> "hello");
        System.out.println(s);
        test_consumer("123", e-> System.out.println(e));
        boolean b = test_predicate("123", e -> e.equals("123"));
        System.out.println(b);
        String s1 = test_function(1, e -> e+1+"0");
        System.out.println(s1);
    }
    public static <T> T test_supplier(Supplier<T> supplier){
        return supplier.get();
    }
    public static <T> void test_consumer(T t,Consumer<T> consumer){
        consumer.accept(t);
    }
    public static <T> boolean test_predicate(T t,Predicate<T> predicate){
        return predicate.test(t);
    }
    public static <R,T> T test_function(R r, Function<R,T> function){
        return function.apply(r);
    }
}

hello
123
true
20
  • 方法引用

java8 方法引用详解

方法引用的三种情形:

1.对象名::实现方法(非静态方法)

2.类::静态方法名

3.类::实例方法(非静态方法)

但是,类::实例方法(非静态方法)这种情形下,需要有前提

前提:方法的第一个参数(这里即为x)是被调用方法(这里指equals())的调用者;方法的第二个参数(这里指y)是被调用方法的参数.

  • 方法引用调用对象的setter方法

import java.util.function.BiConsumer;
import java.util.function.Supplier;

public class Test {
    public static void main(String[] args) {
        testSetter(Node::setNodeId,Node::new);
        System.out.println(111);
    }

    private static <T> void testSetter(BiConsumer<T,String> biConsumer, Supplier<T> supplier){
        T model = supplier.get();
        biConsumer.accept(model,"id");
    }
}
  • 方法引用调用对象的getter方法,没有BiSupplier,是因为Function可以理解成BiSupplier

    /**
     * 补充字段
     *
     * @param fieldModelMap 字段值和snooping日志的map映射
     * @param journeyExtendNodeModel 待补充字段的实例
     * @param ownFieldGetter 已有值的字段get方法
     * @param fillFieldGetter 待补充值的字段get方法
     * @param fillFieldSetter 待补充值的字段set方法
     */
    private void fillField(Map<String, JourneyExtendNodeModel> fieldModelMap,
        JourneyExtendNodeModel journeyExtendNodeModel, Function<JourneyExtendNodeModel, String> ownFieldGetter,
        Function<JourneyExtendNodeModel, String> fillFieldGetter,
        BiConsumer<JourneyExtendNodeModel, String> fillFieldSetter) {
        if (fillFieldGetter.apply(journeyExtendNodeModel) == null && fieldModelMap.containsKey(
            ownFieldGetter.apply(journeyExtendNodeModel))) {
            fillFieldSetter.accept(journeyExtendNodeModel,
                fillFieldGetter.apply(fieldModelMap.get(ownFieldGetter.apply(journeyExtendNodeModel))));
        }
    }

动物装饰