EnumSet-移动交叉点的有效方式



我有两个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)

如果我理解得对,那么在不进行第二次收集的情况下进行此操作的方法如下:

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();
    }
}

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

但你所做的似乎并不是非常低效,我个人也不会担心。这些实际上都是很小的物体。如果这个操作每秒完成10000次,并且被证明是一个瓶颈,那么很可能需要重新设计该功能,这样它就不会使用集合。

相关内容

  • 没有找到相关文章

最新更新