当前位置: 首页 > 知识库问答 >
问题:

Java 9将具有可为空字段的对象列表处理为另一列表

井旺
2023-03-14

我有一个清单

@Getter
@Setter
public class Person {
    private String name;
    private boolean value_bool;
    private String value_string;
    private Integer value_integer;
    private String value_text;
}

问题是,对于一个Person来说,只有一个字段(除了name之外)是实际启动的(例如non-null),其他的字段都是null,所以对于其中的4个值,有4个Person实例,每个实例都有一个name和一个值。我如何将这个Person对象列表转换为value对象列表,最好使用StreamAPI?

共有1个答案

扈沛
2023-03-14

布尔值_bool不能为

要合并此数据,首先要按name分组,然后将列表 (表示所有具有相同名称的单独的Person对象)折叠为一个合并的Person。

要分组:

Map<String, List<Person>> grouped = persons.stream()
.collect(Collectors.groupingBy(Person::getName));

列表 合并到单个人员中并不特别适合基于流的代码。我会做一个方法,这有点复杂,因为你有很多不明显的选择要做。例如,假设您有2带有value_bool为false,1带有true。和2个Person对象都有一个非空的value_string,并且它们不是同一个字符串;哪一个赢了,还是应该抛出一个异常,还是应该将字符串串联起来?

这样的问题存在,而且没有明显的答案,这一事实应该强烈地表明,没有简单的单行程序可以做到这一点。

因此,类似于:

public class Person {
 // ....
  public static Person merge(@NonNull Collection<? extends Person> persons) {
    if (persons.isEmpty()) throw new IllegalArgumentException(
      "Cannot merge an empty list of persons");
    if (persons.size() == 1) return persons.iterator().next();
    Person out = null;
    for (Person person : persons) {
        if (out == null) {
          out = person;
          continue;
        }
        // If any part-person is 'valueBool', the output is also.
        if (person.isValueBool()) out.setValueBool(true);
        // For the rest, the 'last' non-null value 'wins':
        if (person.getValueString() != null) out.setValueString(person.getValueString());
        // etc
    }
    return out;
  }
}

用这种方法武装起来:

persons.stream()
  .collect(Collectors.groupingBy(Person::getName))
  .values()
  .stream()
  .map(Person::merge)
  .collect(Collectors.toList());

其中最后一行可以是tolist();(如果您有JDK16)。

 类似资料:
  • 我的RESTendpoint返回包含对象字段的响应对象。序列化一切正常,但当我开始为此API编写客户端时,我遇到了反序列化问题。我根据一些关于使用Jackson进行多态序列化的问题/文章制作了这个示例代码。它演示了这个问题。 我的期望(以及我对列表的期望 我现在拥有的Object: 但我需要反序列化除动物列表之外的其他类型的对象。救命啊!

  • 问题内容: 我有SourceObjects列表,我需要将其转换为ResultObjects列表。 我可以使用ResultObject的方法将一个对象获取到另一个对象: 我当然可以这样: 但对于能够展示如何使用 rxJava 进行相同操作的人,我将非常感激。 问题答案: 如果发出,则可以使用以下运算符: (将您的列表转换为可观察项) (将您的商品转换为其他商品) 运算符(将完成的Observable

  • 我有2个对象ExpertJpa到ExpertDto的现有映射,需要另一个参数来过滤ExpertJpa。这个映射工作正常,现在我尝试将ExpertJpa列表转换为ExpertDto列表,我添加了第二个参数。 在构建时,我收到错误消息,即List是一个接口,不能是实例…… 错误:(53,18) java:返回类型java.util.List是一个抽象类或接口。提供非抽象/非接口结果类型或工厂方法。

  • 嗨,我有两个对象列表。清单1和清单2 App1中的员工列表 在sql中,我们可以很容易地通过ID列进行连接。但是这里要点击seperate API来阅读清单2。 我可以从清单2创建map,并将EmpId作为键,继续从map获取对象,并将详细信息设置到清单1。 想知道有没有更好的方法来做这件事。

  • 我有一个方法,它接受一个内部有的对象: MatchData k可以是null,有时k.getWatchListDetail()也可以是null。 我需要检查两种情况。首先,如果它能抛出NPE。 上面的实现可以做到这一点,但我尝试使用或带有链接的流,所以我可以在一行链接中完成。

  • 问题内容: 我想使用Java 8技巧在一行中执行以下操作。 给定此对象定义: 和a ,我想得到a ,它是第一个列表中所有s对象的列表- 顺序相同。 我可以使用Java中的循环来做到这一点,但我相信Java8中应该有一个单行lambda可以做到这一点。我无法在线找到解决方案。也许我没有使用正确的搜索词。 有人可以为这种转换建议一个lambda或另一种线吗? 问题答案: 这应该可以解决问题: 也就是说