相同的方法,不同的枚举,如何设计父class?

Same methods, different enums, how to design a parent class?

我的两个类型 class 称为 SearchType 和 ResultcodeType 需要一个优雅的父 class。如何设计这两个 classes 和一个父 class 都以干净和节省代码的方式继承?

public enum SearchType {
    BARCODE(0),
    TEXT(1);

    SearchType(int i)
    {
        this.type = i;
    }

    private int type;

    public static SearchType getType(int value) {
        for (SearchType searchType : SearchType.values()) {
            if (searchType.type == value)
                return searchType;
        }
        throw new IllegalArgumentException("SearchType not found.");
    }

    public int getNumericType() {
        return type;
    }
}

public enum ResultcodeType {
    RESULTS(0),
    NO_RESULTS(1),
    PROBLEMS(2),
    NO_VALUE(-1);

    ResultcodeType(int i)
    {
        this.type = i;
    }

    private int type;

    public static ResultcodeType getType(int value) {
        for (ResultcodeType resultcodeType : ResultcodeType.values()) {
            if (resultcodeType.type == value)
               return resultcodeType;
        }
        throw new IllegalArgumentException("ResultcodeType not found.");
    }

    public int getNumericType() {
        return type;
    }
}

我在哪里使用 SearchType / ResultCodeType?

布局数据绑定

<ImageView
    app:srcCompat="@{item.searchType == SearchType.BARCODE ? @drawable/ic_barcode : @drawable/ic_one_loupe}" 
/>

房间数据库转换器class(又是冗余)。但是现在 room 不能在它的 TypeConverter 中处理泛型类型。所以这将保持原样。

@TypeConverter
public static SearchType SearchTypeFromInt(Integer value) {
    return SearchType.getType(value);
}

@TypeConverter
public static ResultcodeType ResultcodeTypeFromInt(Integer value) {
    return ResultcodeType.getType(value);
}

POJO(带房间注释)

@NonNull
@ColumnInfo(name = "resultcode", defaultValue="-1")
private ResultcodeType mResultcode;

您的枚举可以实现接口并添加默认方法。

例如:

interface Typed {
   Typed getType(int value) 

public enum ResultcodeType implements Typed {
    public Typed getType(int value) {
        for (ResultcodeType resultcodeType : 
        ResultcodeType.values()) {
            if (resultcodeType.type == value)
               return resultcodeType;
        }
        throw new IllegalArgumentException("ResultcodeType not found.");
    }


.... 
} 

我还建议使用地图而不是搜索的以下方法。事实上,您所需要的只是映射。您甚至不需要提供价值。请注意,您不能从构造函数中引用静态值,因此您必须在外部构建映射。

   enum SearchType {
      BARCODE(0), TEXT(1), UNKNOWN(-1);
      static Map<Integer, SearchType> map =
            Map.of(0, SearchType.BARCODE, 1, SearchType.TEXT);

      SearchType(int i) {
         this.type = i;
      }

      private int type;

      public static SearchType getType(int value) {
         return SearchType.map.getOrDefault(value, SearchType.UNKNOWN);
      }

      public int getNumericType() {
         return type;
      }
   }

   public static void main(String[] args) {

      System.out.println(SearchType.getType(0));
      System.out.println(SearchType.getType(1));
      System.out.println(SearchType.getType(99));

   }

由于枚举不能有基数 类,我认为这是最接近的:

public interface Typed {
    int getNumericType();

    static <E extends Enum<E> & Typed> E getType(E[] values, int type) {
        for (E value : values)
            if (value.getNumericType() == type)
                return value;
        throw new IllegalArgumentException(values[0].getClass().getSimpleName() +
                                           " not found: " + type);
    }
}
public enum SearchType implements Typed {
    BARCODE(0),
    TEXT(1);

    private final int type;

    private SearchType(int type) {
        this.type = type;
    }

    @Override
    public int getNumericType() {
        return this.type;
    }

    public static SearchType getType(int type) {
        return Typed.getType(values(), type);
    }
}
public enum ResultcodeType implements Typed {
    RESULTS(0),
    NO_RESULTS(1),
    PROBLEMS(2),
    NO_VALUE(-1);

    private final int type;

    private ResultcodeType(int type) {
        this.type = type;
    }

    @Override
    public int getNumericType() {
        return this.type;
    }

    public static ResultcodeType getType(int type) {
        return Typed.getType(values(), type);
    }
}