【问题标题】:Write generic method which takes enum and string as arguments编写以枚举和字符串为参数的通用方法
【发布时间】:2020-12-30 13:18:17
【问题描述】:

请提出建议。假设我有两个枚举,如下所示。如果枚举值与我的字符串匹配,我正在执行任务。

public enum Action {
        DO("DO"),
        REDO("REDO"),
        ROLLBACK("DONT");

        private String value;

        private Action(String value) {
            this.value = value;
        }

        public String getValue() {
            return this.value;
        }
    }

public enum Days {
        WEEK("WORK"),
        LEAVE("DONT WORK");

        private String value;

        private Days(String value) {
            this.value = value;
        }

        public String getValue() {
            return this.value;
        }
    }

我希望下面的工作对这两种情况都是通用的:

//any String 
String sp ="do";

        Arrays.stream(Action.values()).forEach(e ->{
            if(e.getValue().equalsIgnoreCase(sp)){
                //System.out.println(sp); Some work to do here

            }
        } );

【问题讨论】:

  • 你能解释一下你所说的“通用”是什么意思吗?您想如何调用泛型方法?
  • @Sweeper 例如:我想检查枚举值是否与我的字符串匹配我想返回或打印枚举的名称/值或至少返回 true,因为我不想写相同的每个枚举的代码行。如果我错了,请更正/建议我(Java 新手)有什么方法可以像我们为对象一样编写方法:public static <T> void myFunc(T myObject){ // do something return; }
  • @alwaysabeginner 那么,您希望 T 是 Action 还是 Days?
  • 要在两种类型中通用,第一个先决条件是确保它们来自相同的层次结构!
  • @CommanderTvis 可以是任何其他以类似方式实现的枚举。谢谢

标签: java generics java-8 enums


【解决方案1】:

这段代码中你唯一需要的就是两个枚举:

    Arrays.stream(Action.values()).forEach(e ->{
        if(e.getValue().equalsIgnoreCase(sp)){
            //System.out.println(sp); Some work to do here

        }
    } );

getValue 方法。

所以你可以创建一个有这个方法的接口:

interface HasValue {
    String getValue();
}

让两个枚举都实现接口:

public enum Action implements HasValue {
    ...
}

public enum Days implements HasValue {
    ...
}

然后你可以写一个泛型方法:

public <T extends HasValue> void foo(T[] values, String sp) {
    Arrays.stream(values).forEach(e ->{
        if(e.getValue().equalsIgnoreCase(sp)){
            //System.out.println(sp);

        }
    });
}

你可以这样称呼它:

foo(Action.values(), sp);
foo(Days.values(), sp);

该方法实际上不必是通用的。你可以这样做:

public void foo(HasValue[] values, String sp) {
    ...
}

如果无法更改DaysAction,则可以改用函数式接口:

public <T> void foo(T[] values, Function<T, String> getValue, String sp) {
    Arrays.stream(values).forEach(e ->{
        if(getValue.apply(e).equalsIgnoreCase(sp)){
            //System.out.println(sp);

        }
    });
}

// usage:

foo(Action.values(), Action::getValue, sp);
foo(Days.values(), Days::getValue, sp);

【讨论】:

  • 感谢您的回答,但我指的枚举是外部 jar 的一部分,无法更改/修改。
  • 非常感谢。这就是我一直在寻找的。我可能使用了不正确的问题标题。
  • 您也可以重构出.values(),并让方法采用Class&lt;T&gt; 其中&lt;T extends Enum&lt;T&gt;&gt;,并在方法调用.getEnumConstants() 中获取值,尽管我猜这不会'没有那么简单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-06
  • 1970-01-01
  • 2014-05-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多