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

de.invation.code.toval.misc.ListUtils Maven / Gradle / Ivy

Go to download

TOVAL comprises a set of java classes for common programming issues. It includes utils for arrays, lists, sets and collections for convenient handling and modification, but also support for mathematic definitions concerning logic (clauses + resolution) together with some algorithms for permutations, powersets and resolution. Additionally it contains a number of types for multisets, matrices with object keys and much more.

The newest version!
package de.invation.code.toval.misc;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

import de.invation.code.toval.file.FileWriter;
import de.invation.code.toval.math.CombinationsCalculator;
import de.invation.code.toval.math.Permutations;
import de.invation.code.toval.types.HashList;


public class ListUtils {
	
	private static java.util.Random rand = new Random();
	
	/**
	 * Returns a random element of the given list.
	 * @param  Type of list elements
	 * @param list List
	 * @return Random element of list
	 */
	public static  T getRandomItem(List list){
		return list.get(rand.nextInt(list.size()));
	}
	
	/**
	 * Inserts a header
	 * @param 
	 * @param list
	 * @param headerValue
	 * @param headerSize
	 */
	public static  void insertHeader(List list, T headerValue, int headerSize){
		for(int i=0; inull-value entries for every missing intermediate integer value.
	 * @param list List containing integer values
	 * @return An expanded list containing null values for missing intermediate integer values
	 */
	public static List fillUpWithNulls(List list){
		return fillUpWithNulls(list, null);
	}
	
	/**
	 * Expands an integer list to a size equal to its value range
	 * and adds null-value entries for every missing intermediate integer value.
	 * If replace is not null, all original values are replaced by replace.
	 * @param list List containing integer values
	 * @param replace Replacement for existing values within list
	 * @return An expanded list containing null values for missing intermediate integer values
	 * and optionally replaced original values
	 */
	public static List fillUpWithNulls(List list, Integer replace){
		Collections.sort(list);
		int minValue = list.get(0);
		int maxValue = list.get(list.size()-1);
		int range = (int) (maxValue-Math.signum(minValue)*Math.abs(minValue));
		
		ArrayList result = new ArrayList(range+1);
		for(int i=0; i void swapElements(List list, T element1, T element2){
		int index1 = list.indexOf(element1);
		int index2 = list.indexOf(element2);
		if(index1 == -1 || index1 == -1){
			return;
		}
		Collections.swap(list, index1, index2);
	}
	
	/**
	 * Returns a new list containing all elements of the original list but exclude
	 * @param  Type of list elements
	 * @param list Basic list for operation
	 * @param exclude Element to exclude
	 * @return A new List containing all elements of the original list but exclude
	 */
	public static  List getListWithout(List list, T exclude){
		List result = new ArrayList(list.size());
		for(T t: list)
			if(!t.equals(exclude))
				result.add(t);
		return result;
	}
	
	/**
	 * Returns a new list containing all elements of the original list but the elements in exclude
	 * @param  Type of list elements
	 * @param list Basic list for operation
	 * @param exclude Elements to exclude
	 * @return A new List containing all elements of the original list but the elements in exclude
	 */
	public static  List getListWithout(List list, List exclude){
		List result = new ArrayList(list.size());
		for(T t: list)
			if(!exclude.contains(t))
				result.add(t);
		return result;
	}
	
	public static  boolean containsOnlyNulls(List list){
		for(T t: list)
			if(t!=null)
				return false;
		return true;
	}

	/**
	 * Converts a list to an array of the same type.
	 * @param  Type of list elements
	 * @param list Basic list for operation
	 * @return An array of the same type containing all elements of list
	 */
	@SuppressWarnings("unchecked")
	public static  T[] asArray(List list) {
		return (T[]) list.toArray();
	}
	
	/**
	 * Creates a mutable list containing n copies of value.
	 * @param  Type of list elements
	 * @param value Basic value for list generation
	 * @param n Number of copies
	 * @return A mutable list containing n copies of value
	 */
	public static  List createList(T value, int n){
		ArrayList result = new ArrayList(n);
		for(int i=0; isize incrementing integer values beginning with begin.
	 * @param size Number of integer values within the result list
	 * @param begin First integer to start with
	 * @return A list containing incrementing integer values beginning with the specified value
	 */
	public static List createAndInitializeList(int size, int begin){
		ArrayList result = new ArrayList(size);
		for(int i=begin; icuts.
* Cuts are interpreted in an inclusive way, which means that a single cut at position i * divides the given list in 0...i-1 + i...n
* This method deals with both cut positions including and excluding start and end-indexes
* @param Type of list elements * @param list The list to divide * @param cuts Cut positions for divide operations * @return A list of sublists of list according to the given cut positions */ public static List> divideList(List list, Integer... cuts) { Arrays.sort(cuts); int c = cuts.length; if(cuts[0]<0 || cuts[c-1]>list.size()-1) throw new IllegalArgumentException(); int startIndex = cuts[0]==0 ? 1 : 0; if(cuts[c-1]!=list.size()-1) { cuts = Arrays.copyOf(cuts, cuts.length+1); cuts[cuts.length-1] = list.size()-1; c++; } List> result = new ArrayList>(c-startIndex); int lastEnd = 0; for(int i=startIndex; i<=c-1; i++) { int c2 = icuts.
* Cuts are interpreted in an inclusive way, which means that a single cut at position i * divides the given list in 0...i-1 + i...n
* This method deals with both cut positions including and excluding start and end-indexes
* @param list List to divide * @param cuts Cut positions for divide operations * @return A list of sublists of list according to the given cut positions * @see #divideList(List, Integer...) */ public static List> divideObjectList(List list, Integer... cuts) { return divideList(list, cuts); } public static List> randomPartition(List coll, int number){ List> checkResult = checkPartitionConditions(coll, number); if(checkResult!=null) return checkResult; HashList cuts = new HashList(); while(cuts.size()0 && nextInt List> exponentialPartition(List coll, int number){ List> checkResult = checkPartitionConditions(coll, number); if(checkResult!=null) return checkResult; HashList cuts = new HashList(); Double factor = Math.max(3.0, 3.0 + (3.0-number))/Math.max(3, 3.0 + (number-3.0)); for(int i=-1; i>(-1)*number; i--){ int cut = (int) Math.ceil(Math.exp(factor*i)*coll.size()); if(cut == coll.size() || (!cuts.isEmpty() && cut==cuts.get(cuts.size()-1))) cut -= 1; cuts.add(cut); } return divideList(coll, cuts.toArray(new Integer[1])); } private static List> checkPartitionConditions(List coll, int number){ if(coll==null || coll.isEmpty() || number<1 || number>coll.size()) throw new IllegalArgumentException(); if(number==1){ List> result = new ArrayList>(); result.add(coll); return result; } if(number == coll.size()) return divideAsList(coll); return null; } /** * Returns a list of lists containing exactly one element of the given list each. * @param coll The list to split * @return A list of lists containing exactly one element of the given list each. */ public static List> divideAsList(List coll){ List> result = new ArrayList>(); for(T t: coll){ ArrayList list = new ArrayList(); list.add(t); result.add(list); } return result; } /** * Returns a new list containing all elements of the original list with an index in [from;to] * @param Type of list elements * @param list Basic list for operation * @param from Start-index (inclusive) for copy operation * @param to End-index (inclusive) for copy operation * @return The sublist of list starting at index from and ending at index to */ public static List copyOfRange(List list, int from, int to) { if(from<0 || from >=list.size() || to<0 || to>=list.size() || from>to) throw new IllegalArgumentException("Illegal extraction bounds"); ArrayList result = new ArrayList(to-from+1); for(int i=from; i<=to; i++) result.add(list.get(i)); return result; } /** * Returns a copy of the given list. * @param Type of list elements * @param list List to copy * @return Copy of list containing the same elements */ public static List copyOf(List list) { ArrayList result = new ArrayList(list.size()); result.addAll(list); return result; } /** * Returns a string list representation of the given list. * @param coll List to convert * @return A list containing string representations for all elements of the input list. */ public static List asStringList(List coll){ List result = new ArrayList(); for(Object t: coll){ result.add(t.toString()); } return result; } public static String toString(List coll, char delimiter){ StringBuilder builder = new StringBuilder(); for(int i=0; i Type of list elements * @param list Basic list for permutations * @return Iterator holding all possible permutations */ public static ListPermutations getPermutations(List list){ return new ListPermutations(list); } public static List> getPartitions(List list, Integer... elementCounts){ int totalCount = 0; for(Integer elements: elementCounts) totalCount += elements; if(totalCount!=list.size()) return null; Integer[] cuts = new Integer[elementCounts.length-1]; for(int i=0; i> result = new ArrayList>(); Iterator> permutations = getPermutations(list); while(permutations.hasNext()){ Partition part = new Partition(list); List> dividedList = divideList(permutations.next(), cuts); for(List l: dividedList) part.addSubset(l); result.add(part); } return result; } /** * Generates a random sublist of list, that contains at most maxCount elements. * @param Type of list elements * @param list Basic list for operation * @param maxCount Maximum number of items * @return A sublist with at most maxCount elements */ public static List getRandomSublistMax(List list, int maxCount){ int count = rand.nextInt(maxCount)+1; return getRandomSublist(list, count); } /** * Generates a random sublist of list, that contains at least maxCount elements. * @param Type of list elements * @param list Basic list for operation * @param minCount Minimum number of items * @return A sublist with at least minCount elements */ public static List getRandomSublistMin(List list, int minCount){ int count = RandomUtils.randomIntBetween(minCount, list.size()); return getRandomSublist(list, count); } /** * Generates a random sublist of list, that contains exactly maxCount elements. * @param Type of list elements * @param list Basic list for operation * @param count Number of items * @return A sublist with exactly count elements */ public static List getRandomSublist(List list, int count){ List result = new ArrayList(); ArrayList opSet = new ArrayList(list); while(result.size() Type of list elements. */ public static class ListPermutations extends Permutations> { private List list; public ListPermutations(List list) { super(list.size()); this.list = list; } /** * Returns a new list with permuted elements. * @return A new list with permuted elements */ @Override public List next() { Integer[] next = super.nextPermutation(); List newList = new ArrayList(); for (int i = 0; i < next.length; i++) { newList.add(i, list.get(next[i])); } return newList; } } public static class Partition { private List basicSet = null; private List> subsets = new ArrayList>(); private int elements = 0; public Partition(List basicSet){ this.basicSet = basicSet; } public List getSubset(int index){ return subsets.get(index); } public void addSubset(List subset){ if(basicSet.containsAll(subset) && (elements+subset.size())<=basicSet.size()){ subsets.add(subset); elements += subset.size(); } } @Override public String toString(){ StringBuilder builder = new StringBuilder(); for(List subset: subsets){ builder.append(subset); builder.append(' '); } return builder.toString(); } } public static List> getKElementaryLists(List list, int k) { // OLD METHOD: // Is way slower than the new one and needs bit count calculation // The usage of integer or long restricts the applicability to input list sizes < 63! // if(list.size()<0) // throw new IllegalArgumentException("set size 0"); // List> result = new ArrayList>(); // for (int i = 0; i < Math.pow(2, list.size()); i++) { // int setSize = Integer.bitCount(i); // if(setSize == k){ // List newList = new ArrayList(setSize); // result.add(newList); // for (int j = 0; j < list.size(); j++) { // if ((i & (1 << j)) != 0) { // newList.add(list.get(j)); // } // } // } // } // return result; List> result = new ArrayList>(); CombinationsCalculator calc = new CombinationsCalculator(list, k); while(calc.hasNext()){ result.add(Arrays.asList(calc.next())); } return result; } public static List> getBiPartitions(List input, int sizeOfFirstPartition){ List> result = new ArrayList>(); boolean reverse = input.size()-sizeOfFirstPartition> r = rek(input, 0, input.size()-1-sizeOfFirstPartition, Math.min(sizeOfFirstPartition, input.size()-sizeOfFirstPartition)-1,""); for(List l: r){ Partition part = new Partition(input); if(reverse){ part.addSubset(ListUtils.getListWithout(input, l)); part.addSubset(l); } else { part.addSubset(l); part.addSubset(ListUtils.getListWithout(input, l)); } result.add(part); } return result; } public static List> rek(List input, int startIndex, int endIndex, int number, String header){ // System.out.println(header+"call("+startIndex+", "+endIndex+", "+number+")"); // System.out.println(header+"start: "+startIndex+", end: "+endIndex+", number: "+number); // System.out.println(input + " " + itemIndex); List> result = new ArrayList>(); if(number==0){ // System.out.println(header+"return trivial result"); for(int i=startIndex; i newList = new ArrayList(); newList.add(input.get(i)); result.add(newList); // System.out.println(header+"add: "+newList); } } else { // // System.out.println(header+"go deeper"); for(int i=startIndex; i<=endIndex; i++){ // System.out.println(header+"i = "+i); T head = input.get(i); // System.out.println(header+"head: "+head); List> rekResult = rek(input, i+1, endIndex+1, number-1, header+" "); for(List list: rekResult){ List newList = new ArrayList(Collections.singletonList(head)); newList.addAll(list); result.add(newList); // System.out.println(header+"add: "+newList); } } } // System.out.println(header+"return "+result); return result; } private static void precompileBitCountNumbers() throws IOException{ int power = 63; int maxBitCount = 5; Map writers = new HashMap(); Map counters = new HashMap(); for(int i=2; i<=maxBitCount; i++){ FileWriter newWriter = new FileWriter(System.getProperty("user.dir") + "/bitCount" + i + "Numbers"); // newWriter.writeLine("long[] bitCount"+i+"Numbers = {"); writers.put(i, newWriter); counters.put(i, 0L); } for(long i=1L; i < Math.pow(2, power) - 1; i++){ long bitCount = Long.bitCount(i); for(int j=2; j<=maxBitCount; j++){ if(j >= power) break; if(bitCount == j){ counters.put(j, counters.get(j) + 1); writers.get(j).writeLine(i); // if(counters.get(j) > 1 && counters.get(j) % 10 == 0){ // writers.get(j).writeLine('+'); // } continue; } } if(i % 10000000L == 0) System.out.println(i / (Long.MAX_VALUE + 0.0)); } for(FileWriter writer: writers.values()){ // writer.writeLine("};"); writer.closeFile(); } } }