ValueAccessPointComparator.java
package org.codefilarete.reflection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
/**
* Comparator for {@link ValueAccessPoint} that makes them not different if their goal is to access same property
* whatever the way they use (by field, by method, by method reference ...)
* Based on {@link #compareTo(AccessorDefinition, AccessorDefinition)}.
* This class also uses a cache to store {@link AccessorDefinition} (which helps comparison) which can be shared
* between instances. See {@link #ValueAccessPointComparator(Map)} to give your shared {@link Map} instance.
*
* @author Guillaume Mary
*/
public class ValueAccessPointComparator implements Comparator<ValueAccessPoint> {
/** Since {@link AccessorDefinition} computation can be costly we use a cache, it may be shared between instances */
private final Map<ValueAccessPoint, AccessorDefinition> cache;
/**
* Default constructor
*/
public ValueAccessPointComparator() {
this(new HashMap<>());
}
/**
* Constructor that uses the given cache for {@link AccessorDefinition} computation.
*
* @param cache a {@link Map} used as cache for finding {@link AccessorDefinition} of a {@link ValueAccessPoint}
*/
public ValueAccessPointComparator(Map<ValueAccessPoint, AccessorDefinition> cache) {
this.cache = cache;
}
@Override
public int compare(ValueAccessPoint o1, ValueAccessPoint o2) {
AccessorDefinition accessorDefinition1 = cache.computeIfAbsent(o1, AccessorDefinition::giveDefinition);
AccessorDefinition accessorDefinition2 = cache.computeIfAbsent(o2, AccessorDefinition::giveDefinition);
return compareTo(accessorDefinition1, accessorDefinition2);
}
protected int compareTo(AccessorDefinition o1, AccessorDefinition o2) {
int comparison = o2.getDeclaringClass().getName().compareTo(o1.getDeclaringClass().getName());
if (comparison == 0) {
comparison = o2.getName().compareTo(o1.getName());
if (comparison == 0) {
comparison = o2.getMemberType().toString().compareTo(o1.getMemberType().toString());
}
}
return comparison;
}
}