【问题标题】:Can I map between values inside enums?我可以在枚举内的值之间映射吗?
【发布时间】:2019-08-01 03:41:18
【问题描述】:

我创建了具有两个值的枚举:品牌名称和品牌代码。
我想通过输入品牌名称来知道品牌代码。
我也想通过输入品牌代码来知道品牌名称。
这个问题可以用 Enum 解决吗?还是其他代码更有效?我想让代码尽可能短

我创建了以下代码来搜索品牌代码。如果我想反之亦然,我可以创建另一个 Hashmap 和方法来将代码转换为品牌。但这是解决问题的有效方法吗?

public enum Brand{
  COLA("cola", "CL8935"),
  BREAD("bread", "BR2810"),
  SNICKERS("snickers", "SN4423");

  private static final Map<String, String> BY_BRAND = new HashMap<>();

  static {
    for (Brand brand : values()){
       BY_BRAND.put(brand.code, brand.brand);
    }
  }

  private final String brand;
  private final String code;

  public static String convertToCode(String brand){
    return BY_BRAND.get(brand.toLowerCase()).toString();
  } 
}

【问题讨论】:

  • 非常有效。或者,如果它只是几个项目,您可以循环。或者使用 BiMap。
  • 您似乎在这里混淆了许多东西,并没有显示您的其余代码。
  • @chrylis 我没有把所有内容都写出来,因为我的问题就在这里。代码的其余部分只是一个调用此枚举内部方法的主类。一个 sn-p 打电话给Brand.convertToCode("the brand input");
  • 只是一个 note:在 put 中使用 code 作为键,但在 get 中使用 brand.toLowerCase - 肯定不会返回(假设 brand 是构造函数中的第一个值,如"cola"code 构造函数中的第二个值,如"CL8935") - 在这里似乎混合了两种情况(有效是一个非常广泛的术语)
  • @CarlosHeuberger 哎呀,关键应该是brand

标签: java spring-boot java-8 enums


【解决方案1】:

更新 - 添加完整枚举(带导入)

import java.util.Arrays;
import java.util.function.Function;

enum Brand {

   COLA("cola", "CL8935"),
   BREAD("bread", "BR2810"),
   SNICKERS("snickers", "SN4423");

   private final String brand;

   private final String code;

   Brand(String brand, String code) {
      this.brand = brand;
      this.code = code;
   }

   public static Brand findBy(String value, Function<Brand, String> extractor) {
      return Arrays.stream(Brand.values())
            .filter(brand -> extractor.apply(brand).equalsIgnoreCase(value))
            .findFirst()
            .orElse("Either a default or throw exception here");
   }

   public String getBrand() {
      return brand;
   }

   public String getCode() {
      return code;
   }

}

原创

您可以使用静态 findBy 方法作为地图的替代方法。这将允许您传入 getter 的值和方法引用,用于比较存储在枚举中的值。

这里的区别在于性能(因为映射会更快),事实上您将返回枚举并且您很可能想要默认枚举值或在找不到匹配项时抛出异常。下面是一个例子

 public static Brand findBy(String value, Function<Brand, String> extractor) {
      return Arrays.stream(Brand.values())
            .filter(brand -> extractor.apply(brand).equalsIgnoreCase(value))
            .findFirst()
            .orElse("Either a default or throw exception here");
   }

而且可以这样调用

public static void main(String[] args) {
      Brand brand1 = Brand.findBy("cola", Brand::getBrand);
      Brand brand2 = Brand.findBy("BR2810", Brand::getCode);
   }

【讨论】:

  • 这个方法是在 Enum 类中创建的吗?因为我无法解析 Arrays 类型。快速修复也不建议我导入它。嗯
  • 是的,我会用全班(包括进口)更新我的答案
  • 问题是“我想通过输入品牌名称知道品牌代码。我也想通过输入品牌代码知道品牌名称。”因此,要完全回答这个问题,您还需要另外两种方法,例如:public static String getBrand(String code) { return findBy(code, Brand::getCode).getBrand(); }
【解决方案2】:

Brand 中的简单静态方法应该这样做:

  public static String getBrand(String code) {
       for(Brand b : Brand.values()){
           if(b.getCode().equals(code)) return b.getBrand();
       }
       return null;
   }

同样你可以写一个getCode(String brand)


编辑:假设这两个属性没有相同的值,你可以检查做双向映射在相同的方法:
  public static String getOtherAttribute(String value) {

       for(Brand b : Brand.values()){
           if(b.getCode().equals(value)) return b.getBrand();
           if(b.getBrand().equals(value)) return b.getCode();
       }

       return null;
   }

如果这两个属性可能具有相同的值,您可以在方法的签名中添加一个参数(标志)来告诉您要检索哪个属性。

【讨论】:

  • 是的,这个方法会起作用。我只是想知道我是否可以在一个方法中映射双向关系:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-04
  • 1970-01-01
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-23
相关资源
最近更新 更多