[英]Java generics variable <T> value
At the moment I am using the following code to do some filtering in jpa: 目前我正在使用以下代码在jpa中进行一些过滤:
if (value.getClass() == Integer.class) {
return cb.greaterThan(root.<Integer>get(field), (Integer) value);
} else if (value.getClass() == Long.class) {
return cb.greaterThan(root.<Long>get(field), (Long) value);
} else if (value.getClass() == Float.class) {
return cb.greaterThan(root.<Float>get(field), (Float) value);
} else if (value.getClass() == Date.class) {
return cb.greaterThan(root.<Date>get(field), (Date) value);
}
How can i reduce this block to one line like that? 我怎样才能将这个块减少到一行呢?
return cb.greaterThan(root.<value.getClass()>get(field), value);
So i need to replace the T value in < T > with my class type. 所以我需要用我的类类型替换<T>中的T值。 Sadly i am not that good in java generics. 可悲的是,我在java泛型中并不是那么好。 Does anybody has an idea? 有人有想法吗? Is it even possible? 它甚至可能吗?
root is of the following type: http://docs.oracle.com/javaee/6/api/javax/persistence/criteria/Path.html#get%28java.lang.String%29 root具有以下类型: http : //docs.oracle.com/javaee/6/api/javax/persistence/criteria/Path.html#get%28java.lang.String%29
edit: here is the full class i want to write: 编辑:这是我要写的完整课程:
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
public class FilterExpression {
public static final Integer BEGINS_WITH = 0;
public static final Integer ENDS_WITH = 1;
public static final Integer CONTAINS = 2;
public static final Integer EQUAL = 3;
public static final Integer NOT_EQUAL = 4;
public static final Integer GREATER_THAN = 5;
public static final Integer GREATER_EQUAL_THAN = 6;
public static final Integer LESS_THAN = 7;
public static final Integer LESS_EQUAL_THAN = 8;
private static final Map<String, Integer> OPERATOR_MAPPING;
static {
Map<String, Integer> temp = new HashMap<>();
temp.put("bw", BEGINS_WITH);
temp.put("ew", ENDS_WITH);
temp.put("ct", CONTAINS);
temp.put("eq", EQUAL);
temp.put("nq", NOT_EQUAL);
temp.put("gt", GREATER_THAN);
temp.put("gq", GREATER_EQUAL_THAN);
temp.put("lt", LESS_THAN);
temp.put("lq", LESS_EQUAL_THAN);
OPERATOR_MAPPING = Collections.unmodifiableMap(temp);
}
private String field;
private Integer operator;
private Object value;
public FilterExpression(String field, String operator, String value, Class c) {
this.field = field;
setOperator(operator);
setValue(value, c);
}
public Boolean validate() {
if (StringUtils.isEmpty(field) || operator == null || value == null) {
return false;
}
Class c = value.getClass();
if (c == String.class) {
return operator >= BEGINS_WITH && operator <= NOT_EQUAL;
} else if (c == Integer.class || c == Float.class || c == Double.class) {
return (EQUAL >= EQUAL && operator <= LESS_EQUAL_THAN);
} else if (c == Boolean.class) {
return operator == EQUAL || operator == NOT_EQUAL;
} else if (c == Identification.Type.class) {
return operator == EQUAL || operator == NOT_EQUAL;
}
return false;
}
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public Integer getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = OPERATOR_MAPPING.get(operator.toLowerCase());
}
public Object getValue() {
return value;
}
public void setValue(String s, Class c) {
try {
if (Boolean.class == c) {
this.value = validateBoolean(s);
} else if (Integer.class == c) {
this.value = Integer.parseInt(s);
} else if (Float.class == c) {
this.value = Float.parseFloat(s);
} else if (Identification.Type.class == c) {
this.value = Identification.Type.parse(Integer.parseInt(s));
} else {
this.value = s;
}
} catch (NumberFormatException ex) {
this.value = null;
}
}
public <R> Predicate toPredicate(CriteriaBuilder cb, Root<R> root) {
if (Objects.equals(operator, FilterExpression.EQUAL)) {
return cb.equal(root.get(field), value);
} else if (Objects.equals(operator, FilterExpression.NOT_EQUAL)) {
return cb.notEqual(root.get(field), value);
} else if (Objects.equals(operator, FilterExpression.CONTAINS)) {
return cb.like(root.<String>get(field), "%" + value + "%");
} else if (Objects.equals(operator, FilterExpression.ENDS_WITH)) {
return cb.like(root.<String>get(field), "%" + value);
} else if (Objects.equals(operator, FilterExpression.BEGINS_WITH)) {
return cb.like(root.<String>get(field), value + "%");
} else if (Objects.equals(operator, FilterExpression.GREATER_THAN)) {
if (value.getClass() == Integer.class) {
return cb.greaterThan(root.<Integer>get(field), (Integer) value);
} else if (value.getClass() == Float.class) {
return cb.greaterThan(root.<Float>get(field), (Float) value);
} else if (value.getClass() == Date.class) {
return cb.greaterThan(root.<Date>get(field), (Date) value);
}
} else if (Objects.equals(operator, FilterExpression.GREATER_EQUAL_THAN)) {
if (value.getClass() == Integer.class) {
return cb.greaterThanOrEqualTo(root.<Integer>get(field), (Integer) value);
} else if (value.getClass() == Float.class) {
return cb.greaterThanOrEqualTo(root.<Float>get(field), (Float) value);
} else if (value.getClass() == Date.class) {
return cb.greaterThanOrEqualTo(root.<Date>get(field), (Date) value);
}
} else if (Objects.equals(operator, FilterExpression.LESS_THAN)) {
if (value.getClass() == Integer.class) {
return cb.lessThan(root.<Integer>get(field), (Integer) value);
} else if (value.getClass() == Float.class) {
return cb.lessThan(root.<Float>get(field), (Float) value);
} else if (value.getClass() == Date.class) {
return cb.lessThan(root.<Date>get(field), (Date) value);
}
} else if (Objects.equals(operator, FilterExpression.LESS_EQUAL_THAN)) {
if (value.getClass() == Integer.class) {
return cb.lessThanOrEqualTo(root.<Integer>get(field), (Integer) value);
} else if (value.getClass() == Float.class) {
return cb.lessThanOrEqualTo(root.<Float>get(field), (Float) value);
} else if (value.getClass() == Date.class) {
return cb.lessThanOrEqualTo(root.<Date>get(field), (Date) value);
}
}
return null;
}
I guess you could make the whole class generic. 我想你可以让全班通用。
public class FilterExpression<T extends Comparable<T>> {
//Make value to be type T instead of Object.
T value;
// And you could easily do,
...
return cb.greaterThan(root.<T>get(field), value);
}
由于你的方法的代码很复杂,因为一切都是混合的,如果你不打算为我重构你的方法,到目前为止最简单的解决方案是依赖原始类型作为下一个:
return cb.greaterThan(root.<Comparable>get(field), (Comparable) value);
With the two answers from codebender and nicolas filotto i was able to do it. 有了codebender和nicolas filotto的两个答案,我就能做到。 I had to remove the setValue method to put it outside the class. 我不得不删除setValue方法将它放在类之外。 So here is the complete class: 所以这是完整的课程:
public class FilterExpression<T extends Comparable<T>> {
public static final Integer BEGINS_WITH = 0;
public static final Integer ENDS_WITH = 1;
public static final Integer CONTAINS = 2;
public static final Integer EQUAL = 3;
public static final Integer NOT_EQUAL = 4;
public static final Integer GREATER_THAN = 5;
public static final Integer GREATER_EQUAL_THAN = 6;
public static final Integer LESS_THAN = 7;
public static final Integer LESS_EQUAL_THAN = 8;
private static final Map<String, Integer> OPERATOR_MAPPING;
static {
Map<String, Integer> temp = new HashMap<>();
temp.put("bw", BEGINS_WITH);
temp.put("ew", ENDS_WITH);
temp.put("ct", CONTAINS);
temp.put("eq", EQUAL);
temp.put("nq", NOT_EQUAL);
temp.put("gt", GREATER_THAN);
temp.put("gq", GREATER_EQUAL_THAN);
temp.put("lt", LESS_THAN);
temp.put("lq", LESS_EQUAL_THAN);
OPERATOR_MAPPING = Collections.unmodifiableMap(temp);
}
private String field;
private Integer operator;
private T value;
public FilterExpression(String field, String operator, T value) {
this.field = field;
setOperator(operator);
this.value = value;
}
public Boolean validate() {
if (StringUtils.isEmpty(field) || operator == null || value == null) {
return false;
}
Class c = value.getClass();
if (c == String.class) {
return operator >= BEGINS_WITH && operator <= NOT_EQUAL;
} else if (c == Integer.class || c == Float.class || c == Double.class || c == Date.class) {
return (EQUAL >= EQUAL && operator <= LESS_EQUAL_THAN);
} else if (c == Boolean.class) {
return operator == EQUAL || operator == NOT_EQUAL;
} else if (c == Identification.Type.class) {
return operator == EQUAL || operator == NOT_EQUAL;
}
return false;
}
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public Integer getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = OPERATOR_MAPPING.get(operator.toLowerCase());
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public <R> Predicate toPredicate(CriteriaBuilder cb, Root<R> root) {
if (Objects.equals(operator, FilterExpression.EQUAL)) {
return cb.equal(root.<T>get(field), value);
} else if (Objects.equals(operator, FilterExpression.NOT_EQUAL)) {
return cb.notEqual(root.<T>get(field), value);
} else if (Objects.equals(operator, FilterExpression.CONTAINS)) {
return cb.like(root.<String>get(field), "%" + value + "%");
} else if (Objects.equals(operator, FilterExpression.ENDS_WITH)) {
return cb.like(root.<String>get(field), "%" + value);
} else if (Objects.equals(operator, FilterExpression.BEGINS_WITH)) {
return cb.like(root.<String>get(field), value + "%");
} else if (Objects.equals(operator, FilterExpression.GREATER_THAN)) {
return cb.greaterThan(root.<T>get(field), (T) value);
} else if (Objects.equals(operator, FilterExpression.GREATER_EQUAL_THAN)) {
return cb.greaterThanOrEqualTo(root.<T>get(field), (T) value);
} else if (Objects.equals(operator, FilterExpression.LESS_THAN)) {
return cb.lessThan(root.<T>get(field), (T) value);
} else if (Objects.equals(operator, FilterExpression.LESS_EQUAL_THAN)) {
return cb.lessThanOrEqualTo(root.<T>get(field), (T) value);
}
return null;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.