Java 我应该选择fromValue()函数枚举的哪种方法

Java 我应该选择fromValue()函数枚举的哪种方法,java,performance,optimization,enums,Java,Performance,Optimization,Enums,嗨,我想在枚举中提供fromValue()函数。请您提供宝贵的建议,我应该选择哪种方法:- 这里我们每次迭代枚举值并返回匹配的结果 在这种方法中,我们使用静态块和返回值创建键值映射,无需迭代。但这里我们需要使用“静态块” 公众普查日{ public static Day fromValue(final String value) { for (Day day: values()) { if (day.value.equals(value)) {

嗨,我想在枚举中提供fromValue()函数。请您提供宝贵的建议,我应该选择哪种方法:-

  • 这里我们每次迭代枚举值并返回匹配的结果
  • 在这种方法中,我们使用静态块和返回值创建键值映射,无需迭代。但这里我们需要使用“静态块”
  • 
    公众普查日{

     public static Day fromValue(final String value) {
         for (Day day: values()) {
             if (day.value.equals(value)) {
                 return day;
             }
         }
         return UNKNOWN;
      }
    
    SUNDAY(“星期日”),
    星期一(“星期一”),
    星期二(“星期二”),
    未知(“未知”);
    私有最终字符串值;
    日期(最终字符串值){
    这个值=值;
    }
    私有静态最终映射值_TO_TYPE=new HashMap();
    静止的{
    Stream.of(DAY.values()).forEach(type->VALUE_TO_type.put(type.VALUE,type));
    }
    公共字符串值(){
    返回值;
    }
    公共静态日fromValue(最终字符串值){
    最后一天=值\u TO \u TYPE.get(值);
    返回日期!=空?日期:未知;
    }
    }
    

    我更喜欢第一种方法,因为它更干净

    第二种方法可能会在不同键具有相同值时失败。在这种情况下,您必须更改地图构建逻辑。第一种方法将简单地返回第一个匹配的键

    当Java在内部搜索映射中的键时,通过将值保持为map do,您并没有取消搜索操作

    使用内置的valueOf()函数-

    private static Day[] VALUES = values();
    
    方案2的控制流程 如果将SOP添加到构造函数和静态块,则会得到的输出:

    继续星期日
    继续星期一
    继续星期二
    内容未知
    静态blk


    因此,除非您对静态块有所了解,否则第二个选项的性能可能更高。

    我只想保持代码简单,并实现
    fromValue()
    迭代
    values()
    数组:

    
    public enum DAY {

        SUNDAY("sunday"),
        MONDAY("monday"),
        TUESDAY("tuesday"),
        UNKNOWN("unknown");
    
        private final String value;
    
        DAY(final String value) {
            this.value = value;
        }
    
        private static final Map<String, DAY> VALUE_TO_TYPE = Stream.of(DAY.values()).collect(Collectors.toMap(d -> d.value, d -> d));
    
        public String value() {
            return value;
        }
    
       public static Optional<DAY> fromValue(final String value) {
           return Optional.ofNullable(VALUE_TO_TYPE.get(value));
       }
    }
    
    在正常大小的枚举中,与将值存储在
    静态
    映射中的解决方案相比,此实现的性能可能不会有任何明显的差异。如果你关心绩效,你应该首先衡量它。只有在确定了代码库的这一部分是性能瓶颈之后,才应该开始“优化”它

    只需调用一次
    values()
    (在引擎盖下进行阵列克隆)并将阵列存储在
    静态
    变量中,就可以稍微“优化”上述代码:


    使用第二种方法,稍作修改

    
    公众普查日{

     public static Day fromValue(final String value) {
         for (Day day: values()) {
             if (day.value.equals(value)) {
                 return day;
             }
         }
         return UNKNOWN;
      }
    
    SUNDAY(“星期日”),
    星期一(“星期一”),
    星期二(“星期二”),
    未知(“未知”);
    私有最终字符串值;
    日期(最终字符串值){
    这个值=值;
    }
    私有静态最终映射值_TO_TYPE=Stream.of(DAY.values()).collect(Collectors.toMap(d->d.VALUE,d->d));
    公共字符串值(){
    返回值;
    }
    公共静态可选fromValue(最终字符串值){
    返回可选的.ofNullable(VALUE_TO_TYPE.get(VALUE));
    }
    }
    

    第二种方法看起来更好,因为它在可读性方面更有效。但是这两个实现并不相同,因为参数不匹配。在第一个示例中,您从不返回
    null
    ,而是返回
    UNKNOWN
    值,而在第二个示例中,您可以返回
    null
    。你为什么还要费心安排
    周一(“周一”)
    。那只是无用的复制。考虑到这被标记为
    performance
    optimization
    ,你在错误的地方尝试优化。顺便说一句-你可以使用
    private static final Map VALUE_to_TYPE=Stream.of(DAY.values()).collect(Collectors.toMap(d->d.VALUE(),d->d)),完全避免静态块这取决于枚举的大小。如果只有7个元素,那么在数组中搜索的速度要么与使用哈希集的速度一样快,要么差异可能无法测量。选项1似乎更容易阅读。但这两个版本都足够可读。他们之间没有太多选择。对于100000个元素的大枚举,考虑选项2,但首先测量性能。顺便说一下,出于兴趣,我检查了Oracle的EntudioEnimult.ValueFoF()。它使用了您的选项2。这是一个小枚举,所以我怀疑它会有多大区别,但是(通常)哈希映射搜索比迭代搜索快……而且,如果我知道我的值可能重复什么,我仍然可以处理映射中的逻辑。在流的情况下,您永远无法确定可能返回哪个值。此外,与在map中查找散列位置相比,一遍又一遍地迭代相同的数据结构以查找相同的值对我来说没有意义(肯定是在大型枚举方面)。当没有项目非常少时,我看不到map over list的任何性能改进。Hashmap方法我们复制对象并为枚举值保留双内存空间。我在很多时候都遇到过类似的需求,每次我都使用列表方法,因为这看起来更干净。这对于op发布的枚举是一个很好的解决方案,但它不适用于相同模式的所有枚举,因为
    不能保证匹配枚举名称。。。而且,
    valueOf
    永远不会返回null,它会抛出一个异常,谢谢!根据更新的答案在实际应用程序中,值不会硬编码为“星期一”、“星期二”等,而是从国际化属性文件中读取。支持的每种语言一套。所以这个解决方案行不通。
    private static Day[] VALUES = values();
    
    
    public enum DAY {

        SUNDAY("sunday"),
        MONDAY("monday"),
        TUESDAY("tuesday"),
        UNKNOWN("unknown");
    
        private final String value;
    
        DAY(final String value) {
            this.value = value;
        }
    
        private static final Map<String, DAY> VALUE_TO_TYPE = Stream.of(DAY.values()).collect(Collectors.toMap(d -> d.value, d -> d));
    
        public String value() {
            return value;
        }
    
       public static Optional<DAY> fromValue(final String value) {
           return Optional.ofNullable(VALUE_TO_TYPE.get(value));
       }
    }