将列表<Object>转换为映射键<键、列表<Object>>使用对象的属性作为键



我有一个包含以下元素的对象Foo:

class Foo {
    int id;
    int departmentId;
    boolean condition1;
    boolean condition2;
    boolean condition3;
    //...
}

以及 Foo 对象列表(~10k 个条目(:

List<Foo> fooList = new ArrayList<>();
fooList.add(...);
//...

我需要遍历此列表的每个 DepartmentId,并且能够在特定 DepartmentId 的对象满足特定条件组合时停止其任何进一步迭代。

为此,我想简单地创建一个新的 Map,它将我的 DepartmentId 作为键,并将所有相关的 Foo 对象作为其值。这样我就可以基于 DepartmentId 循环访问我的新对象,并在满足条件后轻松停止具有相同 Id 的其他部门的迭代。像这样:

Map<Foo.departmentId, List<Foo>> departmentFoos = new HashMap<>();

除了遍历我的fooList并逐个放置/替换我的HashMap的对象之外,是否可以以更好的方式实现这一点?

因此,就迭代次数而言,转换为Map不太可能给您带来任何好处,您最好只是浏览列表并就地处理。这是必需的,因为在浏览了整个Foo列表之前,无法知道是否已达到特定部门 ID 的最后一次出现。

所以我会做这样的事情:

for (Foo foo : fooList) {
  if (hasBeenProcessed(foo.departmentId) {
    continue;
  }
  process(foo);
}

请注意,根据您的需要,hasBeenProcessed可以像processedDepartmentIds.contains(foo.departmentId)一样简单。

对于仅将其转换为地图,没有什么可以避免浏览整个列表。在像Guava:Maps.toMap或Guava:Multimaps.index这样的库中有一些方便的方法。

使用流,可以通过以下方式完成:

Map<Integer, List<Foo>> output = fooList.stream()
                .collect(Collectors.groupingBy(Foo::getDepartmentId, Collectors.toList()));

最新更新