【问题标题】:Convert SortedSet to a TreeMap or ImmutableMap with keys as iterator position将 SortedSet 转换为以键为迭代器位置的 TreeMap 或 ImmutableMap
【发布时间】:2019-10-25 21:22:39
【问题描述】:

我有一个 SortedSet<MyObject>MyObject 有一些 compareTo Date 的逻辑。

class MyObject {
   .. many fields
   private Date date;

   @Override
    public int compareTo(MyObject object) {
    .. logic here..
    }    

}

我想将此SortedSet 转换为TreeMap 或Guava 的ImmutableSortedMap,并将键作为SortedSet 中元素的位置。

例如

0 -> MyObject1
1 -> MyObject2
...and so on

我可以遍历 SortedSet 并将元素手动放入新的 TreeMap,但我想知道是否有更简洁的方法可以通过 Streams 或 Guava 库/Collection 库来完成。

【问题讨论】:

  • 请注意,由从零开始的连续整数键索引的映射实际上是List。所以,ImmutableList.copyOf(yourSet) 可以工作。
  • 你的班级是否实现了 Comparable?
  • 是的,它确实实现了Comparable<MyObject>
  • 我不明白这个with keys as positions of keys
  • 对不起,我的意思是元素在 SortedSet 中的位置

标签: java data-structures java-stream guava


【解决方案1】:

只需循环即可。

TreeMap<Integer, MyClass> map = new TreeMap<>();
for (MyClass myClass : sortedSet) {
  map.put(map.size(), myClass);
}

我发现这比 Bohemian 提出的流方法要清晰得多。

【讨论】:

  • ……如果你想不惜一切代价引入 lambdas,你仍然可以使用sortedSet.forEach(item -&gt; map.put(map.size(), item));
【解决方案2】:

您的 TreeMap 想法不正是数组的含义吗?

MyObject[] myObjects = sortedMap.toArray();

【讨论】:

  • 是的,现在有点像,但我更喜欢 TreeMap,因为它不会像 List 那样增长,因为索引。
【解决方案3】:

使用流外部的有效最终计数器变量。

由于插入是有序的,你不需要最终的地图是TreeMap;可以是更快的LinkedHashMap,它的迭代顺序和插入一样。

AtomicInteger counter = new AtomicInteger();
Map<Integer, MyClass> map = sortedSet.stream()
  .collect(Collectors.toMap(
    x -> counter.getAndIncrement(),
    x -> x,
    (a, b) -> a,
    LinkedHashMap::new));

如果您迫切需要TreeMap,请将上面代码中的LinkedHashMap 替换为TreeMap

【讨论】:

  • 不会为了这个目的而使用AtomicInteger
  • @novice 为什么?使用这样的计数器有什么问题?另外,请注意我的答案的更改。
  • 这依赖于处理顺序与遭遇顺序相同。这个假设不适用于并行流,但规范也故意不保证顺序流的处理顺序。因此,您要为线程安全构造(AtomicInteger 不是免费提供)付出代价,以获得一个不能并行工作并抵消 API 意图的解决方案,同时仍然比 a simple loop 复杂得多……
猜你喜欢
  • 2016-12-14
  • 1970-01-01
  • 1970-01-01
  • 2015-10-25
  • 2011-09-02
  • 2011-10-06
  • 2020-05-18
  • 2011-01-03
相关资源
最近更新 更多