创建一个枚举查找。单个对象的多个键

时间:2018-06-26 09:11:21

标签: java enums java-stream

我一直在使用Joshua Bloch的出色模式来创建从字符串(或其他类型)到枚举对象的查找。创建枚举对象后,我们需要将地图创建为:

    public void loadData (View view){

    OkHttpClient client=new OkHttpClient();
    try {
        client = new OkHttpClient.Builder()
                .sslSocketFactory(new TLSSocketFactory())
                .build();
    } catch (KeyManagementException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }

    String LINK = "https://api.github.com";
    Retrofit retrofit = new Retrofit.Builder ().client(client).baseUrl (LINK).build ();
    GithubServise githubServise= retrofit.create (GithubServise.class);
    githubServise.getGithub ().enqueue (new Callback<ResponseBody> () {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            try {
                textView.setText (response.body ().string ());
                Log.v ("TAG","yes");
            } catch (IOException e) {
                e.printStackTrace ();
            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
           textView.setText ("no data");

        }
    });
}

其中private static final Map<String, MyEnumType> MY_MAP = Stream.of(values()) .collect(toMap(MyEnumType::myFunction, e -> e)); 返回我要映射的字符串。然后,我们创建一个静态方法,该方法使用Map通过键查找对象。

这很好用,但是现在我需要从多个字符串映射每个枚举对象。

我已经更新了myFunction以返回myFunction。现在,我希望我的流在列表上进行迭代,将List<String>对象插入Map中,但是我还无法确定如何实现。

我认为问题在于,如果我创建一个Stream,则会丢失e对象以插入。

更新:对于我要执行的操作似乎有些困惑。我有两个有效的答案(所以我很高兴),但我将添加一个示例,该示例可以帮助正在寻求解决同一问题的任何人。

考虑一个星期几的枚举-该类型中应该恰好有7个对象。我正在尝试从文本描述中编写一种查找方法。 TUESDAY对象需要从两个不同的键-etuesday进行映射。 tue方法将在列表中返回这两个键

出于查找目的,我需要myFunction有两个指向TUESDAY对象的键。

2 个答案:

答案 0 :(得分:1)

我建议多加一行

private static final Map<String, MyEnumType> MY_MAP;

static {
    Map<String, MyEnumType> local = new HashMap<>();
    EnumSet.allOf(MyEnumType.class).forEach(e -> e.getValues().forEach(s -> local.put(s, e)));
    MY_MAP = Collections.unmodifiableMap(local);
}

结果

public enum MyEnumType {

    RED(List.of("red", "dark red")),
    BLUE(List.of("blue", "light blue", "dark blue"));

    private List<String> values;

    MyEnumType(List<String> values)
    {
        this.values = values;
    }

    public List<String> getValues()
    {
        return values;
    }
} 

到映射

red -> RED
blue -> BLUE
light blue -> BLUE
dark red -> RED
dark blue -> BLUE

答案 1 :(得分:1)

正如标题中所述将多个键指向单个对象一样,我想您想将List中的每个对象映射到相同的enum元素,就像有几种获取方法一样< / p>

它将遍历枚举,对于每个枚举,将使用List<Strings>并创建一些Entry(键/值)并将它们与之关联以构建地图

我为演示添加了一个基本枚举,其中myFunction以小写和大写形式返回枚举的名称

 enum AirplaneBrand{    
    AIRBUS(Arrays.asList("A380","A330")),
    BOEING(Arrays.asList("787","737"));       

    private List<String> values;    
    AirplaneBrand(List<String> values){ this.values = values; }    
    public List<String> myFunction(){  return values; }        
  }

    public static void main(String[] args){
        final Map<String, AirplaneBrand> MY_MAP =  
            Stream.of(AirplaneBrand.values())
                  .flatMap(en -> en.myFunction().stream().map(elt -> new AbstractMap.SimpleEntry<String,AirplaneBrand>(elt, en)))
                  .collect(toMap(Entry::getKey, Entry::getValue));

       System.out.println(MY_MAP);                 // {A330=AIRBUS, A380=AIRBUS, 787=BOEING, 737=BOEING}
        System.out.println(MY_MAP.get("737"));     // BOEING
        System.out.println(MY_MAP.get("A380"));    // AIRBUS
    }
}