【问题标题】:How do I filter out a list of enums based on some criteria?如何根据某些标准过滤掉枚举列表?
【发布时间】:2020-06-18 16:12:28
【问题描述】:

假设我有一堂课:

public enum Enums
{
    // about thousand different Enums 
}

我还有一个用户登录的类,根据他是管理员还是普通用户,用户可以访问有限的枚举列表。我知道我可以从类中获取所有枚举的完整列表,但是在 Enums 类不知道用户信息的情况下,按照某些标准过滤这些枚举的优雅方法是什么?

编辑: 这是今天的样子:

@GET
@RolesAllowed({ADMIN})
@Path("/test")
public Response reply(@Auth User user)
{
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("enums", Arrays.toString(Enums.values()));
    return Response.ok(jsonObject.toJSONString()).build();
}

我将返回 1000 多个事件的完整列表,而管理员应该只能看到有限的数量。

【问题讨论】:

  • 一种选择是创建一个类来控制对枚举的访问。一个更好的例子可能会帮助我们帮助您。
  • @user7 如果有帮助,我添加了一些细节
  • 您在哪里维护哪些枚举实例是管理员特定的?
  • 无处自动取款机。这就是为什么我在考虑是否有一种方法可以将其抽象出来,而无需将这些用户特定的详细信息添加到枚举类和过滤中。
  • 这能回答你的问题吗? Finding enum value with Java 8 Stream API

标签: java


【解决方案1】:

让我们以一个工作日名称作为枚举的例子。见下文

public enum DaysOfWeekEnum {

    SUNDAY("off"), 
    MONDAY("working"), 
    TUESDAY("working"), 
    WEDNESDAY("working"), 
    THURSDAY("working"), 
    FRIDAY("working"), 
    SATURDAY("off");

    private String typeOfDay;

    DaysOfWeekEnum(String typeOfDay) {
        this.typeOfDay = typeOfDay;
    }

    // standard getters and setters 

    public static Stream<DaysOfWeekEnum> stream() {
        return Stream.Of(DaysOfWeekEnum.values()); 
    }
}

现在我们将编写一个示例来打印非工作日:

public class EnumStreamExample {

    public static void main() {
        DaysOfWeekEnum.stream()
        .filter(d -> d.getTypeOfDay().equals("off"))
        .forEach(System.out::println);
    }
}

我们运行时得到的输出:

SUNDAY
SATURDAY

对不起,我在电话上,请在回答中格式化代码。

【讨论】:

    【解决方案2】:

    让我们说你的枚举看起来像

    private enum Enums {
        A,
        B,
        C,
        D
    }
    

    其中 A、B 是特定于管理员的。

    创建一个类,允许根据此人是否为管理员访问枚举。

    public class SO {
        EnumSet<Enums> adminEnums = EnumSet.allOf(Enums.class);
        EnumSet<Enums> nonAdminEnums = EnumSet.of(Enums.C, Enums.D);
    
        public Set<Enums> getEnums(User user) {
            boolean isAdmin = user.isAdmin(); //An example
            return isAdmin ? adminEnums : nonAdminEnums;
        }
    

    EnumSet 是一种特殊的 Set 实现,针对存储一组枚举进行了优化。 adminEnums 存储所有枚举的列表,而 nonAdminEnums 具有有限的枚举集。

    您要么必须为管理员显式指定受限枚举列表,要么指定开放枚举并基于此派生另一个。这不仅乏味而且容易出错。以后,当你添加一个新的枚举实例时,你也必须更新它,很容易忘记这一点。

    如果枚举本身包含这样的信息会更好,

    private enum Enums {
        A(false),
        B(false),
        C(true),
        D(true);
    
        private boolean adminSpecific;
        Enums(boolean adminSpecific) {
            this.adminSpecific = adminSpecific;
        }
    
        public boolean isAdminSpecific() {
            return adminSpecific;
        } 
    }
    

    在这种情况下,我们可以根据枚举实例中包含的信息推导出列表。

    Set<Enums> adminEnums = Arrays.stream(Enums.values())
            .filter(Enums::isAdminSpecific)
            .collect(Collectors.toSet());
    

    【讨论】:

    • 这可行,但会有重复,对吗?因为现在我必须为非管理员等重写我想要的所有枚举
    • 我明白了。因此,即使我试图在我的枚举类中避免用户特定的细节......这可能是最好的整体方法
    • 这取决于我的建议是,如果您在枚举中有此信息,则添加新枚举会更容易。但它确实使枚举看起来很难看(IMO),尤其是当你有数百个枚举时。
    猜你喜欢
    • 1970-01-01
    • 2018-09-09
    • 1970-01-01
    • 2011-03-27
    • 2021-06-07
    • 1970-01-01
    • 2016-08-02
    • 2018-01-16
    • 1970-01-01
    相关资源
    最近更新 更多