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

时间:2014-04-25 02:09:51

标签: java enumset

我有两个EnumSets。

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

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)

1 个答案:

答案 0 :(得分:2)

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

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

fromSet.retainAll(MaterialTypes.IMMOVABLE_TYPES);

或明确使用Iterator,以便您可以跳过对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();
    }
}

这样做只会让你在两个集合中创建两个迭代,并且创建了两个对象,而你在OP中执行它的方式更像是每个5个。 addAll / retainAll / removeAll将在内部使用迭代器。

但是你所做的事情似乎并不是非常低效,我个人也不担心。这些实际上是非常小的对象。如果此操作每秒进行10,000次并且它被证明是瓶颈,则更有可能需要重新设计该功能,因此它不会使用集合。