有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!


共 (1) 个答案

  1. # 1 楼答案

    这里的问题是您想在哪里将列表转换为集合, 可以在映射到Class4Class3之前和之后进行转换

    因此,这里的斗争是,如果您想从列表中创建集,然后将其转换为集,或者首先应用从类别3到类别4的转换。这一点很重要,因为列表可以包含重复的值,其中集合只包含唯一的值。将List<Class3>Set<Class3>作为第一个操作将取决于类3对象的相等性。将List<Class4>设为Set<Class4>将检查为类4实现的相等性

    如果您不想显式地声明映射方法,那么总是需要对象之间的小映射器,例如使用复制构造函数Class4(Class3) {...}

    下面是一个例子:

    import lombok.*;
    import java.util.List;
    import java.util.Set;
    import java.util.function.Function;
    import java.util.stream.Collectors;
    
    public class MappingWithLambdas {
        private static Function<Class1,Class2> c1To2WithMapping = c1 -> {
            Function<Class3,Class4> c3to4 = c3 -> {
                Class4 c4 = new Class4();
                c4.setX(c3.getX());
                c4.setY(c3.getY());
                return c4;
            };
            Function<List<Class3>, Set<Class4>> listToSet = l -> l.stream().map(c3to4).collect(Collectors.toSet());
            Class2 c2 = new Class2();
            c2.setX(c1.getX());
            c2.setY(c1.getY());
            c2.setDatas(listToSet.apply(c1.getDatas()));
            return c2;
        };
        public static void main(String[] args) {
            Class1 c1 = new Class1();
            c1.setX("X"); c1.setY("Y");
            c1.setDatas(List.of(new Class3("x", "y"), new Class3("x", "y"), new Class3("x", "y")));
            System.out.println(c1);
            System.out.println("Using mapping function: ");
            System.out.println(c1To2WithMapping.apply(c1));
            Function<Class1,Class2> c1to2WithNew = Class2::new;
            System.out.println("Using Class2 constructor: ");
            System.out.println(c1to2WithNew.apply(c1));
            System.out.println("Simply with constructor: ");
            System.out.println(new Class2(c1));
        }
    }
    @Data
    class Class1 {
        private String x;
        private String y;
        private List<Class3> datas;
    }
    @Data
    class Class2 {
        private String x;
        private String y;
        private Set<Class4> datas;
        private Function<List<Class3>, Set<Class4>> listToSetWithNew = l -> l.stream().map(Class4::new).collect(Collectors.toSet());
        Class2() {}
        Class2(Class1 c) {
            this.x = c.getX();
            this.y = c.getY();
            this.datas = listToSetWithNew.apply(c.getDatas());
    //List<Class3>->List<Class4>->Set<Class4>
    //        this.datas = c.getDatas().stream().map(Class4::new).collect(Collectors.toSet());
    //List<Class3>->Set<Class3>->Set<Class4>
    //        this.datas = new HashSet<>(c.getDatas()).stream().map(Class4::new).collect(Collectors.toSet());
        }
    }
    @Data
    class Class3 {
        private String x;
        private String y;
        Class3(String x, String y) {
            this.x = x;
            this.y = y;
        }
    }
    @Data
    class Class4 {
        private String x;
        private String y;
        Class4() {}
        Class4(Class3 c) {
            this.x = c.getX();
            this.y = c.getY();
        }
    }
    

    @Data注释来自Lombok库,它为我创建了setter、getter和toString

    这个的输出应该类似于:

    Class1(x=X, y=Y, datas=[Class3(x=x, y=y), Class3(x=x, y=y), Class3(x=x, y=y)])
    Class2(x=X, y=Y, datas=[Class4(x=x, y=y)])
    

    编辑: 你仍然可以这样做:

    Class2 c22 = List.of(c1).stream().map(i1 -> {
            Class2 i2 = new Class2();
            i2.setX(i1.getX());
            i2.setY(i1.getY());
            i2.setDatas(i1.getDatas().stream().map(c3 -> {
                Class4 c4 = new Class4();
                c4.setX(c3.getX());
                c4.setY(c3.getY());
                return c4;
            }).collect(Collectors.toSet()));
            return i2;
    }).collect(Collectors.toList()).get(0);
    System.out.println(c22);
    

    但仅仅为了实现这种语法而创建单个对象的列表会降低性能

    编辑2:

    我飞走了一点,在Class1Class2之间创建了映射器,您正在寻找的可能是这样的:

    Function<List<Class3>, Set<Class4>> convertClassesAndToSet = l -> l.stream().map(c3 -> {
            Class4 c4 = new Class4();
            c4.setX(c3.getX());
            c4.setY(c3.getY());
            return c4;
        }).collect(Collectors.toSet());
    Function<List<Class3>, Set<Class4>> toSetAndConvertClasses = l -> new HashSet<>(l).stream().map(c3 -> {
            Class4 c4 = new Class4();
            c4.setX(c3.getX());
            c4.setY(c3.getY());
            return c4;
    }).collect(Collectors.toSet());
    

    或者与您使用的变量名更相关的内容:

    Set<Class4> list3ToList4ThenSet = list1.stream().map(c3 -> {
        Class4 c4 = new Class4();
        c4.setX(c3.getX());
        c4.setY(c3.getY());
        return c4;
    }).collect(Collectors.toSet());
    Set<Class4> list3ToSetThen4 = new HashSet<Class3>(list1).stream().map(c3 -> {
        Class4 c4 = new Class4();
        c4.setX(c3.getX());
        c4.setY(c3.getY());
        return c4;
    }).collect(Collectors.toSet());
    

    编辑3(或4…): 带有Class1到Class2对象列表的示例

    List<Class2> list2WithConstructor = list1.stream().map(Class2::new).collect(Collectors.toList());
    //change this.datas=... in Class2 constructor to:
    this.datas = c.getDatas().stream().map(Class4::new).collect(Collectors.toSet());
    //or to (depending of your use case):
    this.datas = new HashSet<Class3>(c.getDatas()).stream().map(Class4::new).collect(Collectors.toSet());
    //then you will feel the real constructor magic ;P
    

    以及lambdas内部带有mapper的示例:

    List<Class2> list2WithMapper = list1.stream().map(l1 -> {
        Class2 c2 = new Class2();
        c2.setX(l1.getX());
        c2.setY(l1.getY());
        c2.setDatas(l1.getDatas().stream().map(c3 -> {
            Class4 c4 = new Class4();
            c4.setX(c3.getX());
            c4.setY(c3.getY());
            return c4;
        }).collect(Collectors.toSet()));
        return c2;
    }).collect(Collectors.toList());
    

    好了,现在是凌晨1点,我喝醉了,晚安