使用对象的属性作为键将List <Object>转换为Map <key,List <Object >>

时间:2019-06-17 01:12:40

标签: java java-8

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

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

和Foo对象列表(约1万个条目):

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

我需要遍历此列表中的每个departmentId,并且一旦它的对象满足特定条件组合,就能够停止其进一步迭代。

为此,我正在考虑简单地创建一个新Map,将我的departmentId作为键,并将所有相关的Foo对象作为其值。这样,我就可以基于departmentId遍历新对象,并在满足条件后轻松停止具有相同ID的其他部门的迭代。像这样:

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

除了遍历我的fooList和逐个放置/替换HashMap的对象之外,还可以通过其他更好的方法来实现吗?

2 个答案:

答案 0 :(得分:3)

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

所以我会做类似的事情:

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

请注意,hasBeenProcessed可能和processedDepartmentIds.contains(foo.departmentId)一样简单,具体取决于您的需求。

仅将其转换为地图,没有什么可以避免遍历整个列表。在Guava: Maps.toMapGuava: Multimaps.index之类的库中有一些方便的方法。

答案 1 :(得分:2)

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

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