![JAR search and dependency download from the Maven repository](/logo.png)
xdean.jex.extra.RelativeComparator Maven / Gradle / Ivy
The newest version!
package xdean.jex.extra;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import xdean.jex.extra.collection.Tree;
/**
*
*
* @author XDean
*
* @param
*/
@Beta
public class RelativeComparator {
public static > RelativeComparator create() {
return new RelativeComparator(Comparator.naturalOrder());
}
public static RelativeComparator create(Comparator defaultComparator) {
return new RelativeComparator<>(defaultComparator);
}
@SafeVarargs
public static > Comparator of(T... ts) {
return new RelativeComparator(Comparator.naturalOrder()).addOrder(ts).toComparator();
}
@SafeVarargs
public static Comparator of(Comparator defaultComparator, T... ts) {
return new RelativeComparator(defaultComparator).addOrder(ts).toComparator();
}
Comparator defaultComparator;
Tree root;
public RelativeComparator(Comparator defaultComparator) {
this.defaultComparator = defaultComparator;
this.root = new Tree<>(null);
}
@SuppressWarnings("unchecked")
public RelativeComparator addOrder(T... ts) {
for (int i = 0; i < ts.length - 1; i++) {
addOrder(ts[i], ts[i + 1]);
}
return this;
}
public RelativeComparator addOrder(T small, T big) {
Optional> oSmallNode = root.deepChild(small);
Tree smallNode;
if (oSmallNode.isPresent()) {
smallNode = oSmallNode.get();
} else {
smallNode = root.add(small);
}
Optional> oBigNode = root.deepChild(big);
if (oBigNode.isPresent()) {
Tree bigNode = oBigNode.get();
Tree commonParent = smallNode.commonParent(bigNode).get();
if (commonParent == smallNode) {
return this;
} else if (commonParent == bigNode) {
throw new IllegalArgumentException(String.format(
"%s is already bigger than %s, can't setter it as the smaller.", small, big));
} else if (commonParent == bigNode.getParent()) {
smallNode.add(bigNode);
} else if (commonParent == smallNode.getParent()) {
throw new UnsupportedOperationException();
} else {
throw new UnsupportedOperationException();
}
} else {
smallNode.add(big);
}
return this;
}
public Comparator toComparator() {
return root.breadthFirstTraversal()
.skip(1)
.map(Tree::getValue)
.toList()
.> map(orderList -> {
List target = new ArrayList<>(orderList);
target.sort(defaultComparator);
Builder builder = ImmutableMap.builder();
for (int i = 0; i < orderList.size(); i++) {
builder.put(orderList.get(i), target.get(i));
}
ImmutableMap map = builder.build();
return (a, b) -> {
int ia = orderList.indexOf(a);
int ib = orderList.indexOf(b);
if (ia != -1 && ib != -1) {
return ia - ib;
}
return defaultComparator.compare(map.getOrDefault(a, a), map.getOrDefault(b, b));
};
})
.blockingGet();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy