Java

JavaのEnumを別要素で検索する、の検討

本文

ときどき話題になる「JavaのEnumを別要素で検索する」を自分なりに情報収集し、実装してみた
自分的にはまずまずのものになったとは思うが、解決しない問題は多い

ideoneでの試作

test.java
/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.function.*;

interface Searchable {
  public static <T extends Enum,N extends Comparable> Optional<T> getByCode(Supplier<T[]> v,Function<T,N> s,N code) 
  {
    return Arrays.stream(v.get())
                 .filter(data -> s.apply(data).equals(code))
                 .findFirst();
  }
}

enum TestEnum implements Searchable { 
  A(1),B(2),C(3);
  private final Integer id;
  private TestEnum (int id) { this.id = id;}

  public Integer getId() { return id; }

  public static Optional<TestEnum> getById(Integer id){
    return Searchable.getByCode(TestEnum::values,TestEnum::getId,id);
  }
}

/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
  public static void main (String[] args) throws java.lang.Exception
  {
    TestEnum.getById(2).ifPresent(System.out::println);
  }
}

肝となる要素は

  1. valueOf以外での検索(取得)手段を提供する
  2. 任意追加できるようにする ex enum 性別 なら 男性(0,"M"),女性(1,"F")で、getByCode,getBySymbolとかできるようにする
  3. それを持っていることをどうにか識別可能にする(インタフェース)

ただ

  1. 継承するメリットはとくにない(staticは継承はどうしようもない)
  2. クラス情報をジェネリクスで持ってけない(クラスのジェネリクスはstaticで活用できない、イレイジャ的にしょうがないけど)
  3. 2について、メソッドのジェネリクスで持っていった時にT.values()とかもできない、ので、毎度同じような引数が必要
  4. Optionalになる(これは、無い場合があるからしょうがない)
  5. (必要はないとはいえ、基本型メンバはだめ(equalsできないため)、がある)

など、悩む所も多い
正直、Lombokライブラリ的にenumのクラスアクセッサ、メンバアクセッサを付けることで、識別と検索APIを付けれたりしたほうが便利なんだがなあ

追記

コメントでいただいているものを利用の中核に据えるのがよさそう。

考えの元、参考になったリンク