有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

枚举类内的java枚举变量

请为以下情况提供最佳方法:

有一个表,大约有20列
每列都有自己的短名称、全名和类型(数字或字符串)
每种列类型都可以有自己的运算符-例如,String-contains,equals;数字-更多,更少,===
每个操作员都可以有自己的描述

我必须有表类的对象,并且能够查看它的所有列,查看每个列的短名称和全名,使用基于列类型的运算符

我正在尝试使用enum,但我不知道如何将特定列连接到特定类型
例如,如何将“Id”列连接到“StringType”,将“Services”列连接到“NumberType”。 你能帮忙吗

class Table{

    public enum Column {
        Id("id", "ID number"),
        Services("serv", "Services");

        private final String shortName;
        private final String fullName;

        Column(String shortName, String fullName) {
           this.shortName = shortName;
           this.fullName = fullName;
        }

        public String getShortName() {
            return shortName;
        }

        public String getFullName() {
            return fullName;
        }
    }


    public enum StringType{
        contains("String contain another string"),
        equals("String equal a string");

        private final String placeholder;

        StringType(String fullName) {
            this.placeholder = fullName;
        }

        public String getPlaceholder() {
            return placeholder;
        }
    }

    public enum NumberType{
        more("value that is more than input"),
        less("value that is less than input");

        private final String placeholder;

        NumberType(String fullName) {
            this.placeholder = fullName;
        }

        public String getPlaceholder() {
            return placeholder;
        }
    }

}

共 (2) 个答案

  1. # 1 楼答案

    与任何其他类一样,枚举类型可以实现接口。您可以利用这一优势:

    public interface DataType {
        // Deliberately empty.  This is a marker interface.
    }
    
    public enum StringType
    implements DataType {
        // ...
    }
    
    public enum NumberType
    implements DataType {
        // ...
    }
    
    public enum Column {
        Id("id", "ID number", StringType.class),
        Services("serv", "Services", NumberType.class);
    
        private final String shortName;
        private final String fullName;
        private final Class<? extends DataType> type;
    
        Column(String shortName, String fullName, Class<? extends DataType> type) {
           this.shortName = shortName;
           this.fullName = fullName;
           this.type = type;
        }
    
        // ...
    }
    

    如果计划实际使用这些方法来比较数据,则可以向DataType接口添加方法:

    public interface DataType<T> {
        Class<T> getDataClass();
    
        BiPredicate<? super T, ? super T> getTest();
    
        default boolean test(T value1, T value2) {
            return getTest().test(value1, value2);
        }
    
        default boolean testObjects(Object value1, Object value2) {
            Class<T> type = getDataClass();
            return test(type.cast(value1), type.cast(value2));
        }
    }
    
    public enum StringType
    implements DataType<String> {
        contains("String contain another string", String::contains),
        equals("String equal a string", Object::equals);
    
        private final String placeholder;
        private final BiPredicate<? super String, ? super String> test;
    
        StringType(String fullName,
                   BiPredicate<? super String, ? super String> test) {
            this.placeholder = fullName;
            this.test = test;
        }
    
        public String getPlaceholder() {
            return placeholder;
        }
    
        @Override
        public BiPredicate<? super String, ? super String> getTest() {
            return test;
        }
    
        @Override
        public Class<String> getDataClass() {
            return String.class;
        }
    }
    
    public enum NumberType
    implements DataType<Number> {
        more("value that is more than input",
            (n1, n2) -> n1.doubleValue() > n2.doubleValue()),
        less("value that is less than input",
            (n1, n2) -> n1.doubleValue() < n2.doubleValue());
    
        private final String placeholder;
        private final BiPredicate<? super Number, ? super Number> test;
    
        NumberType(String fullName,
                   BiPredicate<? super Number, ? super Number> test) {
            this.placeholder = fullName;
            this.test = test;
        }
    
        public String getPlaceholder() {
            return placeholder;
        }
    
        @Override
        public BiPredicate<? super Number, ? super Number> getTest() {
            return test;
        }
    
        @Override
        public Class<Number> getDataClass() {
            return Number.class;
        }
    }
    
    public enum Column {
        Id("id", "ID number", StringType.class),
        Services("serv", "Services", NumberType.class);
    
        private final String shortName;
        private final String fullName;
        private final Class<? extends DataType<?>> type;
    
        Column(String shortName, String fullName, Class<? extends DataType<?>> type) {
           this.shortName = shortName;
           this.fullName = fullName;
           this.type = type;
        }
    
        // ...
    }
    
  2. # 2 楼答案

    Java有一个Class类,它可以将类型作为其对象,甚至可以处理基元类型
    它没有构造函数,而是一个名为forName()的工厂方法,该方法使用提供的字符串作为参数创建一个类。(尽管这被认为是不好的做法)

    获取类型引用的更好方法是使用类文本。还可以使用getClass()方法从其任何对象获取表示其底层类的Class对象

    以下是使用Class类创建表示类/类型的对象的一些方法: 使用类文本

        Class<?> type1 = int.class;
        Class<?> type2 = boolean.class;
    

    工厂方法

       Class<?> type1 = Class.forName("java.lang.String"); 
    

    最好避免这种方法,因为其中涉及字符串解析,这可能会导致@VGR指出的不必要的运行时错误

    使用对象

       String str = "";
       Class type<?> = str.getClass();
    

    您可以添加Class<?>类型的附加变量,并执行以下操作:

    
     public enum Column {
            Id("id", "ID number", String.class),
            Services("serv", "Services", Number.class);
            Contact("cont", "Contacts", long.class);
    
            private final String shortName;
            private final String fullName;
            private final Class<?> type;
    
            Column(String shortName, String fullName, Class<?> type) {
               this.shortName = shortName;
               this.fullName = fullName;
               this.type = type;
            }
    
            public String getShortName() {
                return shortName;
            }
    
            public String getFullName() {
                return fullName;
            }
           public Class<?> getType() {
                return type;
           }
        }
    

    Class是一个功能强大的类,它有多种方法,如getName()getMethods()。更多信息here

    注意: Class通常用于反射,它有主要缺点,它基本上可以破坏封装,还涉及一些性能开销。 但是,如果您只是为了存储类型信息而使用这个附加字段,那应该没什么大不了的

    **假设您希望将列类型映射到Java类型!**