请针对以下情况提供最佳方法的帮助:
有一个表格,大约有20列。
每列都有自己的短名称,全名和类型(数字或字符串)。
每个列类型可以有自己的运算符-例如,字符串-包含,等于;数字-更多,更少,==,!=
每个操作员都可以有自己的描述。
我必须具有Table类的对象,并且能够查看其所有列,查看每个列的简称和全名,并使用基于列类型的运算符。
我正在尝试使用枚举,但是我不知道如何将特定的列连接到特定的类型。
例如,如何将“ Id”列连接到“ StringType”,如何将“服务”列连接到“ 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;
}
}
}
答案 0 :(得分:2)
像其他任何类一样,枚举类型可以实现接口。您可以利用此优势:
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;
}
// ...
}
答案 1 :(得分:-2)
Java有一个Class
类,可以将类型作为其对象,甚至可以与原始类型一起使用。
它没有构造函数,而是一个名为forName()
的工厂方法,该方法使用提供的String作为其参数创建一个类。(尽管这被认为是不好的做法)。
获取对类型的引用的更好方法是使用类文字。也可以使用Class
方法从其任何对象中获取代表其基础类的getClass()
对象。
您可以通过以下几种方法使用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类型!**