【问题标题】:How to convert multiple list into single list using Java streams?如何使用 Java 流将多个列表转换为单个列表?
【发布时间】:2020-05-25 10:07:59
【问题描述】:

我有一个班级 A 有多个 List 成员。

class A {
    List<X> xList;
    List<Y> yList;
    List<Z> zList;
    
    // getters and setters
}

class X {
     String desc;
     String xtype;
    
     // getters and setters    
}

class Y {   
    String name;
    String ytype;
    
    //getters and setters
}

class Z {
    String description;
    String ztype;
    
    // getters and setters    
}

还有一个只有 2 个属性的类 B

class B {
    String name;
    String type;     
}

我需要遍历A 类中的各种列表并创建B 类对象并添加到这样的列表中:

public void convertList(A a) {  
   List<B> b = new ArrayList<>();
    
    if (!a.getXList().isEmpty()) {
      for (final X x : a.getXList()) {
           b.add(new B(x.getDesc(), x.getXType()));
      }
    }
    
    if (!a.getYList().isEmpty()) {
      for (final Y y : a.getYList()) {
           b.add(new B(y.getName(), y.getYType()));
      }
    }
    
    if (!a.getZList().isEmpty()) {
      for (final Z z : a.getZList()) {
           b.add(new B(z.getDescription(), z.getZType()));
      }
    }    
}

因为 if 和 for 循环在这里重复。

如何使用 Java 流实现这一点?

注意:XYZ 类之间没有关系,也没有通用接口。

【问题讨论】:

  • 您是否尝试过使用 FlatMap,如果没有请看这里。 stackoverflow.com/questions/23112874/…
  • X、Y 和 Z 是扩展同一个基类还是实现包含 getName 和 getType 的同一个接口?
  • 正确解决问题,因为您有多个列表,但将 x,z,y 作为类型传递,但需要 B 的列表。
  • @JoakimDanielson 更新了问题。没有基类或接口。这些类中的属性都是不同的。我需要根据每个类的 getter 转换为 B 类。

标签: java java-stream


【解决方案1】:

由于您的XYZ 类型没有共同的超类型,您必须将它们转换为一些共同的类型,例如Map.Entry&lt;String,String&gt;

您可以创建一个包含所有名称和类型对的Stream,然后将其映射到B 的实例:

List<B> b =
    Stream.of(
        a.getXList().stream().map(x -> new SimpleEntry<>(x.getDesc(),x.getXType())),
        a.getYList().stream().map(y -> new SimpleEntry<>(y.getName(),y.getYType())),
        a.getZList().stream().map(z -> new SimpleEntry<>(z.getDescription(),z.getZType())))
          .flatMap(Function.identity())
          .map(e -> new B(e.getKey(), e.getValue()))
          .collect(Collectors.toList());

或者直接生成B实例:

List<B> b =
    Stream.of(
        a.getXList().stream().map(x -> new B(x.getDesc(),x.getXType())),
        a.getYList().stream().map(y -> new B(y.getName(),y.getYType())),
        a.getZList().stream().map(z -> new B(z.getDescription(),z.getZType())))
          .flatMap(Function.identity())
          .collect(Collectors.toList());

【讨论】:

  • 生成一个 SimpleEntry 然后将其映射到 B 有什么意义?
【解决方案2】:

你可以像下面这样使用Stream.concat()

public List<B> convertList (A a) {
    return Stream.concat(Stream.concat(a.getXList().stream().map(x -> new B(x.getDesc(), x.getXType()))
            , a.getYList().stream().map(y -> new B(y.getName(), y.getYType())))
            , a.getZList().stream().map(z -> new B(z.getDescription(), z.getZType()))).collect(Collectors.toList());
}

【讨论】:

  • @Hadi J 我在 lambda 表达式中得到错误的返回类型。 B 不能转换为 R
  • 我已经在我的本地机器上运行了这个版本,它适用于我
  • 糟糕的是,我在错误的地方戴上了大括号。这看起来不错。谢谢!
【解决方案3】:

由于您没有通用接口,因此您必须使用forEach 方法来遍历每个列表。

a.getXList().forEach(i -> b.add(new B(i.getDesc(), i.getXType())));
a.getYList().forEach(i -> b.add(new B(i.getName(), i.getYType())));
a.getZList().forEach(i -> b.add(new B(i.getDescription(), i.getZType())));

【讨论】:

  • OP 需要java streams 回答,您可以在回答中提及非流式回答。
【解决方案4】:

您使用的是X、Y、Z类的不同属性,没有通用接口,您可以在列表中一一添加。

b.addAll(a.getXList().stream().map(x ->new B(x.getDesc(), x.getXType())).collect(Collectors.toList()));
b.addAll(a.getYList().stream().map(y ->new B(y.getName(), y.getYType())).collect(Collectors.toList()));
b.addAll(a.getZList().stream().map(z ->new B(z.getDescription(), z.getZType())).collect(Collectors.toList()));

【讨论】:

    猜你喜欢
    • 2019-06-12
    • 2018-08-08
    • 1970-01-01
    • 1970-01-01
    • 2019-10-18
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多