java enum新列表创建未按预期工作

时间:2016-04-03 00:26:00

标签: java list enums

好的,这让我很难过,也许我错过了什么。

我有一个枚举类型列表,我正在尝试删除重复项。在下面的代码中,我无法创建新列表,因为列表在迭代期间被清空。

任何人都可以发现这个问题。

List<UserRole> newList = new ArrayList<UserRole>();

for (UserRole userRole: originalList)
{           
        boolean found = false;

        logger.trace("size of new list: check1 = "+newList.size());   <-- size resets to 0

        for (UserRole newRole: newList)
        {
            logger.trace("check "+userRole.name()+ " with "+newRole.name());
            if (StringUtils.equals(newRole.name(),userRole.name()))
            {
                found = true;
                break;
            }
        }

        if (!found)
        {               
            newList.add(userRole);
            logger.trace("size of new list check2= "+newList.size());
        }
}
return newList;

UserRole枚举类看起来像

public enum UserRole {

SYSADMIN,
ADMIN,
STUDENT,
TEACHER,
PRINCIPAL;

public String value() {
    return name();
}

public static UserRole fromValue(String v) {
    return valueOf(v);
}

}

跟踪日志

20:20:22.291 TRACE  44 removeDuplicates - size of new list check1 = 0
20:20:22.291 TRACE  57 removeDuplicates - checking duplicate passed for role = SYSADMIN
20:20:22.291 TRACE  59 removeDuplicates - size of new list check2 = 1
20:20:22.295 TRACE  44 removeDuplicates - size of new list check1 = 0
20:20:22.295 TRACE  57 removeDuplicates - checking duplicate passed for role = SYSADMIN
20:20:22.295 TRACE  59 removeDuplicates - size of new list check2 = 1
20:20:22.296 TRACE  44 removeDuplicates - size of new list check1 = 0
20:20:22.296 TRACE  57 removeDuplicates - checking duplicate passed for role = SYSADMIN
20:20:22.296 TRACE  59 removeDuplicates - size of new list check2 = 1
20:20:22.298 TRACE  44 removeDuplicates - size of new list check1 = 0
20:20:22.298 TRACE  57 removeDuplicates - checking duplicate passed for role = SYSADMIN
20:20:22.298 TRACE  59 removeDuplicates - size of new list check2 = 1

3 个答案:

答案 0 :(得分:2)

显示代码在每次迭代时重置新列表。

但是,您不应该使用List枚举值。请改用EnumSet

作为Set,它会自动防止重复。

ListLinkedHashSet不同,其中order是order-order,而HashSet,其中order是任意的,EnumSet的顺序与枚举的顺序相同值被定义。

此外,EnumSet是紧凑的,并且有很好的辅助方法来处理枚举:

  • EnumSet.copyOf(originalList) 轻松实现您的目标
  • EnumSet.allOf(UserRole.class)
  • EnumSet.noneOf(UserRole.class)
  • EnumSet.of(UserRole.STUDENT, UserRole.TEACHER)
  • EnumSet.complementOf(EnumSet.of(UserRole.SYSADMIN)) 所有枚举,SYSADMIN
  • 除外

答案 1 :(得分:1)

不是错误 - 适用于我 #8&gt; P

我将你的代码复制到一个简单的测试类中 - lo看哪! - 它有效!

我必须假设一些你没有显示的代码,这是调用Sequence.Server的上下文,它产生你给出的日志输出。由于我没有看到你所遇到的问题,我只能认为你的问题在于调用者,而不是方法。如果我正确的话,解释为什么你无法在方法中找到的问题 - 它将围绕调用方法。< / p>

如果这&#34;看那边&#34;建议不足以让您走向解决方案,请编辑并包含调用代码。

PS - 解决此问题的另一种方法是使用集合理论算法,例如:

removeDuplicates(List<UserRole> originalList)

哪个会以不同的方式为您提供所需的结果 - 这是否也会显示问题?如果是这样,那么我 realllly 建议你专注于调用者,而不是被调用者。如果你得到不同的结果,那么你继续看你的方法内部是正确的(尽管你的代码适合我)。

PPS - 如果您希望public static List<UserRole> removeDupesBySetTheory(final List<UserRole> originalList) { final Set<UserRole> holdingSet = new HashSet<>(); holdingSet.addAll(originalList); final List<UserRole> newList = new ArrayList<>(); newList.addAll(holdingSet); return newList; } 保留原始列表的相对排序,请使用removeDupesBySetTheory

答案 2 :(得分:0)

我实际上无法重现您的确切问题,但如果您只想删除重复项,则可以使用Set代替List

Set<UserRole> mySet = EnumSet.noneOf(UserRole.class);

mySet.add(UserRole.SYSADMIN);
mySet.add(UserRole.SYSADMIN);
mySet.add(UserRole.SYSADMIN);
mySet.add(UserRole.TEACHER);

System.out.println(mySet); 

输出为:

[SYSADMIN, TEACHER]