net.automatalib.commons.util.comparison.CmpUtil Maven / Gradle / Ivy
Show all versions of automata-commons-util Show documentation
/* Copyright (C) 2013 TU Dortmund
* This file is part of AutomataLib, http://www.automatalib.net/.
*
* AutomataLib is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 3.0 as published by the Free Software Foundation.
*
* AutomataLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with AutomataLib; if not, see
* http://www.gnu.de/documents/lgpl.en.html.
*/
package net.automatalib.commons.util.comparison;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
/**
* Various methods for dealing with the comparison of objects.
*
* @author Malte Isberner
*
*/
public abstract class CmpUtil {
/**
* Enum for controlling which rank is assigned to a null
* element when using a safe comparator
* ({@link CmpUtil#safeComparator(Comparator, NullOrdering)}).
*
* @author Malte Isberner
*
*/
public static enum NullOrdering {
/**
* null
elements are smaller than all regular elements.
*/
MIN(-1),
/**
* null
elements are bigger than all regular elements.
*/
MAX(1);
/**
* Value that determines the result of the comparison, when
* only the first value is a null
value.
*/
public final int firstNullResult;
private NullOrdering(int firstNullResult) {
this.firstNullResult = firstNullResult;
}
}
/*
* Prevent inheritance.
*/
private CmpUtil() {
}
/**
* Lexicographically compares two {@link Iterable}s. Comparison of the
* elements is done using the specified comparator.
*
* @param o1 the first iterable.
* @param o2 the second iterable.
* @param elemComparator the comparator.
* @return < 0
iff o1 is lexicographically smaller,
* 0
if o1 equals o2 and > 0
otherwise.
*/
public static int lexCompare(Iterable o1, Iterable o2, Comparator elemComparator) {
Iterator it1 = o1.iterator(), it2 = o2.iterator();
while(it1.hasNext() && it2.hasNext()) {
int cmp = elemComparator.compare(it1.next(), it2.next());
if(cmp != 0)
return cmp;
}
if(it1.hasNext())
return 1;
else if(it2.hasNext())
return -1;
return 0;
}
/**
* Lexicographically compares two {@link Iterable}s, whose element types
* are comparable.
* @param o1
* @param o2
* @return
*/
public static > int lexCompare(Iterable o1, Iterable o2) {
Iterator it1 = o1.iterator(), it2 = o2.iterator();
while(it1.hasNext() && it2.hasNext()) {
int cmp = it1.next().compareTo(it2.next());
if(cmp != 0)
return cmp;
}
if(it1.hasNext())
return 1;
else if(it2.hasNext())
return -1;
return 0;
}
/**
* Compares two {@link List}s with respect to canonical ordering.
*
* In canonical ordering, a sequence o1 is less than a sequence o2 if o1 is shorter
* than o2, or if they have the same length and o1 is lexicographically smaller than o2.
* @param o1 the first list
* @param o2 the second list
* @param elemComparator the comparator for comparing the single elements
* @return the result of the comparison
*/
public static int canonicalCompare(List o1, List o2, Comparator elemComparator) {
int siz1 = o1.size(), siz2 = o2.size();
if(siz1 != siz2) {
return siz1 - siz2;
}
return lexCompare(o1, o2, elemComparator);
}
/**
* Compares two {@link List}s of {@link Comparable} elements with respect to canonical ordering.
*
* In canonical ordering, a sequence o1 is less than a sequence o2 if o1 is shorter
* than o2, or if they have the same length and o1 is lexicographically smaller than o2.
* @param o1 the first list
* @param o2 the second list
* @return the result of the comparison
*/
public static > int canonicalCompare(List o1, List o2) {
int siz1 = o1.size(), siz2 = o2.size();
if(siz1 != siz2) {
return siz1 - siz2;
}
return lexCompare(o1, o2);
}
/**
* Retrieves a lexicographical comparator for the given type.
* @param elemComp the comparator to use for comparing the elements.
* @return a comparator for comparing objects of type T
* based on lexicographical ordering.
*/
public static ,U> Comparator lexComparator(Comparator elemComp) {
return new LexComparator(elemComp);
}
/**
* Retrieves a lexicographical comparator for the given type, which has
* to be an {@link Iterable} of {@link Comparable} types.
* @return the lexicographical comparator.
*/
public static ,T extends Iterable> Comparator lexComparator() {
return NaturalLexComparator.getInstance();
}
/**
* Retrieves a canonical comparator for the given list type.
* @param elemComp the comparator to use for comparing the elements.
* @return a comparator for comparing objects of type T
based on
* canonical ordering.
*/
public static ,U> Comparator canonicalComparator(Comparator elemComp) {
return new CanonicalComparator<>(elemComp);
}
/**
* Retrieves a canonical comparator for the given type, which has to be
* a {@link List} of {@link Comparable} types.
* @return the canonical comparator
* @see #canonicalCompare(List, List)
*/
public static ,U extends Comparable> Comparator canonicalComparator() {
return NaturalCanonicalComparator.getInstance();
}
/**
* Retrieves a safe comparator, which can handle null
* element values.
* Whether null
values are smaller or bigger than regular
* values is controlled by the {@link NullOrdering} parameter.
* @param original element class.
* @param baseComp the basic comparator.
* @param nullOrd the ordering policy for null
values.
* @return a safe comparator using the specified underlying comparator.
*/
public static Comparator safeComparator(Comparator baseComp, NullOrdering nullOrd) {
return new SafeComparator(baseComp, nullOrd);
}
/**
* Retrieves a {@link Comparator} that compares elements according to their
* natural ordering (i.e., they have to implement the {@link Comparable}
* interface.
*
* If this comparator is used on elements that don't implement this
* interface, this may result in a {@link ClassCastException}.
*
* @param element class.
* @return the natural ordering comparator.
*/
public static > Comparator naturalOrderingComparator() {
return NaturalOrderingComparator.getInstance();
}
}