All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.automatalib.commons.util.comparison.CmpUtil Maven / Gradle / Ivy

Go to download

Basic utility library containing several useful classes (e.g., a Pair class) to ease everyday programming.

There is a newer version: 0.11.0
Show newest version
/* 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(); } }