com.netflix.infix.NumericValuePredicate Maven / Gradle / Ivy
package com.netflix.infix;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.google.common.primitives.Doubles;
import java.util.Map;
import java.util.Set;
public class NumericValuePredicate implements ValuePredicate {
private Number value;
private Operator op;
public NumericValuePredicate(Number value, String fnName) {
Preconditions.checkNotNull(value, "A null number doesn't make sense. ");
this.value = value;
this.op = Operator.lookup(fnName);
}
public Number getValue() {
return value;
}
public String getOpName () {
return this.op.getOpName();
}
@Override
public boolean apply(Number input) {
Preconditions.checkNotNull(input, "A null number doesn't make sense.");
return op.compare(input, value);
}
private static enum Operator {
GREATER_THAN(">") {
@Override
public boolean compare(Number left, Number right) {
return doComparison(left, right) > 0;
}
},
GREATER_THAN_OR_EQUAL(">=") {
@Override
public boolean compare(Number left, Number right) {
return doComparison(left, right) >= 0;
}
},
LESS_THAN("<") {
@Override
public boolean compare(Number left, Number right) {
return doComparison(left, right) < 0;
}
},
LESS_THAN_OR_EQUAL("<=") {
@Override
public boolean compare(Number left, Number right) {
return doComparison(left, right) <= 0;
}
},
EQUAL("=") {
@Override
public boolean compare(Number left, Number right) {
return doComparison(left, right) == 0;
}
},
NOT_EQUAL("!=") {
@Override
public boolean compare(Number left, Number right) {
return doComparison(left, right) != 0;
}
}
;
private String name;
private Operator(String name) {
this.name = name;
}
public String getOpName() {
return this.name;
}
public static Operator lookup(String opName) {
Operator op = LOOKUP_TABLE.get(opName);
if(op == null){
throw new IllegalArgumentException(
String.format("The operator '%s' is not supported. Supported operations: %s",
opName,
getOperatorNames()
));
}
return op;
}
public static Set getOperatorNames() {
return LOOKUP_TABLE.keySet();
}
private static int doComparison(Number a, Number b) {
return Doubles.compare(a.doubleValue(), b.doubleValue());
}
public abstract boolean compare(Number left, Number right);
// According to JSR-133's FAQ (http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#finalRight),
// " In addition, the visible values for any other object or array referenced by those final
// fields will be at least as up-to-date as the final fields.". Therefore, no need to use sync'd map
// here as this lookup table will be read-only.
private static final Map LOOKUP_TABLE = Maps.newHashMap();
static {
for (Operator op : Operator.values()) {
LOOKUP_TABLE.put(op.getOpName(), op);
}
}
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("NumericValuePredicate [value=");
builder.append(value);
builder.append(", op=");
builder.append(op);
builder.append("]");
return builder.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((op == null) ? 0 : op.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
NumericValuePredicate other = (NumericValuePredicate) obj;
if (op != other.op) {
return false;
}
if (value == null) {
if (other.value != null) {
return false;
}
} else if (!value.equals(other.value)) {
return false;
}
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy