// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.data.osm;
import static java.util.Comparator.comparing;
import static java.util.Comparator.comparingInt;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import org.openstreetmap.josm.gui.DefaultNameFormatter;
import org.openstreetmap.josm.tools.AlphanumComparator;
/**
* Comparators for comparing primitives.
*/
public final class OsmPrimitiveComparator {
/**
* Returns a comparator comparing primitives by their name using {@link DefaultNameFormatter}.
*
* {@linkplain DefaultNameFormatter#format(OsmPrimitive) Formatted names} are cached.
*
* @return a comparator comparing primitives by their name using {@link DefaultNameFormatter}
*/
public static Comparator<OsmPrimitive> comparingNames() {
final Comparator<String> digitsLast = comparing(str -> Character.isDigit(str.charAt(0)) ? 1 : 0);
return comparing(memoize(DefaultNameFormatter.getInstance()::format),
digitsLast.thenComparing(AlphanumComparator.getInstance()));
}
/**
* Returns a comparator comparing primitives by their {@linkplain OsmPrimitive#getUniqueId unique id}.
*
* @return a comparator comparing primitives by their {@linkplain OsmPrimitive#getUniqueId unique id}.
*/
public static Comparator<OsmPrimitive> comparingUniqueId() {
return comparing(OsmPrimitive::getUniqueId);
}
/**
* Returns a comparator ordering the primitives by type in the order NODE, WAY, RELATION
*
* @return a comparator ordering the primitives by type in the order NODE, WAY, RELATION
*/
public static Comparator<OsmPrimitive> orderingNodesWaysRelations() {
return comparingInt(osm -> osm.getType().ordinal());
}
/**
* Returns a comparator ordering the primitives by type in the order WAY, RELATION, NODE
*
* @return a comparator ordering the primitives by type in the order WAY, RELATION, NODE
*/
public static Comparator<OsmPrimitive> orderingWaysRelationsNodes() {
return comparingInt(osm -> {
switch (osm.getType()) {
case WAY:
return 1;
case RELATION:
return 2;
case NODE:
return 3;
default:
throw new IllegalStateException();
}
});
}
/**
* Returns a comparator ordering the primitives by type in the order RELATION, WAY, NODE
*
* @return a comparator ordering the primitives by type in the order RELATION, WAY, NODE
* @since 11679
*/
public static Comparator<OsmPrimitive> orderingRelationsWaysNodes() {
return comparingInt(osm -> {
switch (osm.getType()) {
case RELATION:
return 1;
case WAY:
return 2;
case NODE:
return 3;
default:
throw new IllegalStateException();
}
});
}
private static <T, R> Function<T, R> memoize(Function<T, R> base) {
final Map<T, R> cache = new HashMap<>();
return t -> cache.computeIfAbsent(t, base);
}
private OsmPrimitiveComparator() {
}
}