/*
* This code is copyright (c) 2005-2006, botmachine inc.
* All rights reserved. Use of this code, in whole or in part,
* without express written permission from botmachine inc. is
* a violation of law.
*/
package org.aitools.util;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
/**
* Provides some simple operations on lists.
*
* @author <a href="mailto:noel@aitools.org">Noel Bush</a>
*/
public class Lists {
/**
* Produces a regular expression that will match any member of a given list.
*
* @param list
* @param quote whether or not the items in the list should be quoted (do not quote if items are themselves regexps)
* @return a regular expression that will match any member of a given list
*/
public static String asRegexAlternatives(List<String> list, boolean quote) {
int listSize = list.size();
if (listSize == 0) {
return "";
}
if (listSize == 1) {
String string = list.get(0);
if (quote && !string.startsWith("\\Q") && !string.endsWith("\\E")) {
return Pattern.quote(string);
}
return string;
}
StringBuilder result = new StringBuilder("(");
for (String string : list.subList(0, listSize - 1)) {
if (quote && !string.startsWith("\\Q") && !string.endsWith("\\E")) {
result.append(Pattern.quote(string) + "|");
}
else {
result.append(string + "|");
}
}
if (quote) {
result.append(Pattern.quote(list.get(listSize - 1)) + ")");
}
else {
result.append(list.get(listSize - 1) + ")");
}
return result.toString();
}
/**
* Compares two lists of equal type, by returning a number composed of the sum of all differences of all
* non-overlapping members of the two lists.
*
* @param <T>
* @param oneList
* @param anotherList
* @return the difference between the two lists.
*/
public static <T extends Comparable<?>> int compare(List<T> oneList, List<T> anotherList) {
return compareOneWay(oneList, anotherList) + compareOneWay(anotherList, oneList);
}
/**
* Compares two lists of equal type in one direction only (checking the items from the second list that do not occur
* in the first).
*
* @param <T>
* @param oneList
* @param anotherList
* @return the comparison between the items of the second list that do not appear in the first, and null
*/
private static <T extends Comparable<?>> int compareOneWay(List<T> oneList, List<T> anotherList) {
int result = 0;
if (!oneList.containsAll(anotherList)) {
for (T item : anotherList) {
if (!oneList.contains(item)) {
result += item.compareTo(null);
}
}
}
return result;
}
/**
* Returns the factorial of a given number.
*
* @param number
* @return the factorial of <code>number</code>
*/
public static int factorial(int number) {
if (number > 0) {
return number * factorial(number - 1);
}
return 1;
}
/**
* Produces a list of lists encompassing all permutations of a given list.
*
* @param <T>
* @param list
* @return a list of lists encompassing all permutations of <code>list</code>
*/
public static <T> List<List<T>> getPermutations(List<T> list) {
int listSize = list.size();
if (listSize > 0) {
List<List<T>> results = new ArrayList<List<T>>(factorial(list.size()));
results.add(list);
if (listSize > 1) {
for (T item : list) {
List<T> sublist = new ArrayList<T>(list);
sublist.remove(list.indexOf(item));
for (List<T> permutation : getPermutations(sublist)) {
List<T> newlist = join(item, permutation);
if (!results.contains(newlist)) {
results.add(newlist);
}
}
}
}
return results;
}
return new ArrayList<List<T>>();
}
/**
* Produces a new list that combines the elements of two lists.
*
* @param <T>
* @param list1
* @param list2
* @return a new list that combines the elements of <code>list1</code> and <code>list2</code>
*/
public static <T> List<T> join(List<T> list1, List<T> list2) {
List<T> result = new ArrayList<T>(list1);
result.addAll(list2);
return result;
}
/**
* Produces a new list that combines a single element and the elements of a list.
*
* @param <T>
* @param item
* @param list
* @return a new list that combines <code>item</code> and <code>list</code>
*/
public static <T> List<T> join(T item, List<T> list) {
List<T> result = new ArrayList<T>();
result.add(item);
result.addAll(list);
return result;
}
/**
* Produces a new list that contains a single given item.
*
* @param item
* @param <T>
* @return a new list that contains just <code>item</code>
*/
public static <T> List<T> singleItem(T item) {
List<T> result = new ArrayList<T>(1);
result.add(item);
return result;
}
}