/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
class Ideone{
	
	public static <T extends Comparable<T>> void concurrentSort( final List<T> key, List<?>... lists){
        // Do validation
        if(key == null || lists == null)
        	throw new NullPointerException("key cannot be null.");
        
        for(List<?> list : lists)
        	if(list.size() != key.size())
        		throw new IllegalArgumentException("all lists must be the same size");
        
        // Lists are size 0 or 1, nothing to sort
        if(key.size() < 2)
        	return;
        
        // Create a List of indices
		List<Integer> indices = new ArrayList<Integer>();
		for(int i = 0; i < key.size(); i++)
			indices.add(i);

        // Sort the indices list based on the key
		Collections.sort(indices, new Comparator<Integer>(){
			@Override public int compare(Integer i, Integer j) {
				return key.get(i).compareTo(key.get(j));
			}
		});
		
		Map<Integer, Integer> swapMap = new HashMap<Integer, Integer>(indices.size());
		List<Integer> swapFrom = new ArrayList<Integer>(indices.size()),
					  swapTo   = new ArrayList<Integer>(indices.size());

        // create a mapping that allows sorting of the List by N swaps.
		for(int i = 0; i < key.size(); i++){
			int k = indices.get(i);
			while(i != k && swapMap.containsKey(k))
				k = swapMap.get(k);
			
			swapFrom.add(i);
			swapTo.add(k);
			swapMap.put(i, k);
		}
		
        // use the swap order to sort each list by swapping elements
		for(List<?> list : lists)
			for(int i = 0; i < list.size(); i++)
				Collections.swap(list, swapFrom.get(i), swapTo.get(i));
	}
	
	public static void main (String[] args) throws java.lang.Exception{
		List<Integer> ids = Arrays.asList(0, 1, 2, 3);
		
		// Dupes are allowed
		List<String> colors = Arrays.asList("blue", "yellow", "red", "black");
		
		// List Types do not need to be the same
		List<String> clothes = Arrays.asList("shoes", "pants", "boots", "coat");
		
		System.out.println("======= Before Sort ========");
		System.out.println(ids);
		System.out.println(colors);
		System.out.println(clothes);
		System.out.println();
		System.out.println();
		
		System.out.println("======= Sort By ID =========");
		concurrentSort(ids, ids, colors, clothes);
		System.out.println(ids);
		System.out.println(colors);
		System.out.println(clothes);
		System.out.println();
		System.out.println();
		
		System.out.println("======= Sort By Color =========");
		concurrentSort(colors, ids, colors, clothes);
		System.out.println(ids);
		System.out.println(colors);
		System.out.println(clothes);
		System.out.println();
		System.out.println();
		
		System.out.println("======= Sort By Clothes =========");
		concurrentSort(clothes, ids, colors, clothes);
		System.out.println(ids);
		System.out.println(colors);
		System.out.println(clothes);
		System.out.println();
		System.out.println();
	}
}