【问题标题】:EnumSet - Efficient way to move intersectionEnumSet - 移动交叉点的有效方法
【发布时间】:2014-04-25 02:09:50
【问题描述】:

我有两个 EnumSet。

我想将某些值从一个转移到另一个,但在两个对象中保留那些被认为“不可移动”的值。示例代码...

Public enum  MaterialTypes {

    STONE,
    METAL,
    WOOD,
    STICKS,
    STRAW;

    // STONE & METAL are "immoveable"...
    public static EnumSet<MaterialTypes> IMMOVEABLE_TYPES = EnumSet.of(STONE, METAL);

}

EnumSet<MaterialTypes> fromTypes = EnumSet.of(CellType.STONE, CellType.WOOD, CellType.STICKS);
EnumSet<MaterialTypes> toTypes   = EnumSet.of(CellType.METAL, CellType.STRAW);

// How to preserve the IMMOVEABLE types, but transfer all the other types from one object to the other?
// E.g. Desired result...

// fromTypes = STONE                (i.e. STONE preserved, WOOD & STICKS removed)
// toTypes   = METAL, WOOD, STICKS   (i.e. METAL preserved, STRAW removed, WOOD & STICKS added)

我尝试了各种方法,但都涉及许多步骤和临时 EnumSet 的创建。我想知道是否有一种真正有效的方法以及(当然)它是什么。

这让我头疼!

谢谢。

更新:

我尝试的一种方法(我认为可能效率低下)以达到预期的效果...

EnumSet<MaterialTypes> tmpSet = fromTypes.clone();   // Create temporary copy of fromTypes

tmpSet.removeAll(MaterialTypes.IMMOVEABLE_TYPES);    // Leave only the MOVEABLE types in tmpSet

fromTypes.retainAll(MaterialTypes.IMMOVEABLE_TYPES); // Leave only the IMMOVEABLE type in fromTypes

toTypes.retainAll(MaterialTypes.IMMOVEABLE_TYPES);   // Leave only the IMMOVEABLE types in toTypes

toTypes.addAll(tmpSet);                         // Add the MOVEABLE types (originally in fromTypes)

【问题讨论】:

  • 现在你的例子说toTypes = METAL, WOOD, STRAW (i.e. METAL preserved, STRAW removed, WOOD &amp; STICKS added) 这没有意义。你能纠正一下吗?您能否也请澄清一下您正在尝试做什么?如果可能,请向我们展示您编写的执行此操作但您认为效率不高的代码。
  • 啊 - 已更正,谢谢。 (告诉过你这让我很头疼!)我稍后会添加我尝试过的代码(当我解开我造成的混乱时!;-)
  • 感谢 Radiodef - 我添加了一些似乎可以达到预期结果的代码,但对我来说似乎过于夸张了,特别是因为我非常频繁地执行此方法。

标签: java enumset


【解决方案1】:

如果我的理解是正确的,那么在不进行第二次收集的情况下这样做的方法是这样的:

toSet.retainAll(MaterialTypes.IMMOVABLE_TYPES);
for(MaterialTypes mt : fromSet) {
    if(!MaterialTypes.IMMOVABLE_TYPES.contains(mt))
        toSet.add(mt);
}

fromSet.retainAll(MaterialTypes.IMMOVABLE_TYPES);

或者显式使用迭代器,这样您就可以跳过对retainAll 的调用之一:

toSet.retainAll(MaterialTypes.IMMOVABLE_TYPES);
for(Iterator<MaterialTypes> it = fromSet.iterator(); it.hasNext();) {
    MaterialTypes mt = it.next();
    if(!MaterialTypes.IMMOVABLE_TYPES.contains(mt)) {
        toSet.add(mt);
        it.remove();
    }
}

这样做只需要在 Sets 和创建的 2 个对象中进行两次迭代,而在 OP 中执行此操作的方式更像是每个 5 个。 addAll/retainAll/removeAll 将在内部使用迭代器。

但是你所做的似乎并没有非常低效,我个人不会担心。这些实际上是非常小的物体。如果此操作每秒完成 10,000 次并且被证明是一个瓶颈,则更有可能需要重新设计该功能,以便它不使用集合。

【讨论】:

  • 非常好,感谢 Radiodef 提供这些选项。
猜你喜欢
  • 2020-10-31
  • 2010-09-27
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-07
  • 1970-01-01
  • 2019-05-17
相关资源
最近更新 更多