/* 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)
for(List<?> list : lists)
if(list.size() != key.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
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
)); }
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("======= Sort By ID ========="); concurrentSort(ids, ids, colors, clothes);
System.
out.
println("======= Sort By Color ========="); concurrentSort(colors, ids, colors, clothes);
System.
out.
println("======= Sort By Clothes ========="); concurrentSort(clothes, ids, colors, clothes);
}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5sYW5nLio7CmltcG9ydCBqYXZhLmlvLio7CgovKiBOYW1lIG9mIHRoZSBjbGFzcyBoYXMgdG8gYmUgIk1haW4iIG9ubHkgaWYgdGhlIGNsYXNzIGlzIHB1YmxpYy4gKi8KY2xhc3MgSWRlb25lewoJCglwdWJsaWMgc3RhdGljIDxUIGV4dGVuZHMgQ29tcGFyYWJsZTxUPj4gdm9pZCBjb25jdXJyZW50U29ydCggZmluYWwgTGlzdDxUPiBrZXksIExpc3Q8Pz4uLi4gbGlzdHMpewogICAgICAgIC8vIERvIHZhbGlkYXRpb24KICAgICAgICBpZihrZXkgPT0gbnVsbCB8fCBsaXN0cyA9PSBudWxsKQogICAgICAgIAl0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImtleSBjYW5ub3QgYmUgbnVsbC4iKTsKICAgICAgICAKICAgICAgICBmb3IoTGlzdDw/PiBsaXN0IDogbGlzdHMpCiAgICAgICAgCWlmKGxpc3Quc2l6ZSgpICE9IGtleS5zaXplKCkpCiAgICAgICAgCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJhbGwgbGlzdHMgbXVzdCBiZSB0aGUgc2FtZSBzaXplIik7CiAgICAgICAgCiAgICAgICAgLy8gTGlzdHMgYXJlIHNpemUgMCBvciAxLCBub3RoaW5nIHRvIHNvcnQKICAgICAgICBpZihrZXkuc2l6ZSgpIDwgMikKICAgICAgICAJcmV0dXJuOwogICAgICAgIAogICAgICAgIC8vIENyZWF0ZSBhIExpc3Qgb2YgaW5kaWNlcwoJCUxpc3Q8SW50ZWdlcj4gaW5kaWNlcyA9IG5ldyBBcnJheUxpc3Q8SW50ZWdlcj4oKTsKCQlmb3IoaW50IGkgPSAwOyBpIDwga2V5LnNpemUoKTsgaSsrKQoJCQlpbmRpY2VzLmFkZChpKTsKCiAgICAgICAgLy8gU29ydCB0aGUgaW5kaWNlcyBsaXN0IGJhc2VkIG9uIHRoZSBrZXkKCQlDb2xsZWN0aW9ucy5zb3J0KGluZGljZXMsIG5ldyBDb21wYXJhdG9yPEludGVnZXI+KCl7CgkJCUBPdmVycmlkZSBwdWJsaWMgaW50IGNvbXBhcmUoSW50ZWdlciBpLCBJbnRlZ2VyIGopIHsKCQkJCXJldHVybiBrZXkuZ2V0KGkpLmNvbXBhcmVUbyhrZXkuZ2V0KGopKTsKCQkJfQoJCX0pOwoJCQoJCU1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiBzd2FwTWFwID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgSW50ZWdlcj4oaW5kaWNlcy5zaXplKCkpOwoJCUxpc3Q8SW50ZWdlcj4gc3dhcEZyb20gPSBuZXcgQXJyYXlMaXN0PEludGVnZXI+KGluZGljZXMuc2l6ZSgpKSwKCQkJCQkgIHN3YXBUbyAgID0gbmV3IEFycmF5TGlzdDxJbnRlZ2VyPihpbmRpY2VzLnNpemUoKSk7CgogICAgICAgIC8vIGNyZWF0ZSBhIG1hcHBpbmcgdGhhdCBhbGxvd3Mgc29ydGluZyBvZiB0aGUgTGlzdCBieSBOIHN3YXBzLgoJCWZvcihpbnQgaSA9IDA7IGkgPCBrZXkuc2l6ZSgpOyBpKyspewoJCQlpbnQgayA9IGluZGljZXMuZ2V0KGkpOwoJCQl3aGlsZShpICE9IGsgJiYgc3dhcE1hcC5jb250YWluc0tleShrKSkKCQkJCWsgPSBzd2FwTWFwLmdldChrKTsKCQkJCgkJCXN3YXBGcm9tLmFkZChpKTsKCQkJc3dhcFRvLmFkZChrKTsKCQkJc3dhcE1hcC5wdXQoaSwgayk7CgkJfQoJCQogICAgICAgIC8vIHVzZSB0aGUgc3dhcCBvcmRlciB0byBzb3J0IGVhY2ggbGlzdCBieSBzd2FwcGluZyBlbGVtZW50cwoJCWZvcihMaXN0PD8+IGxpc3QgOiBsaXN0cykKCQkJZm9yKGludCBpID0gMDsgaSA8IGxpc3Quc2l6ZSgpOyBpKyspCgkJCQlDb2xsZWN0aW9ucy5zd2FwKGxpc3QsIHN3YXBGcm9tLmdldChpKSwgc3dhcFRvLmdldChpKSk7Cgl9CgkKCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluIChTdHJpbmdbXSBhcmdzKSB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbnsKCQlMaXN0PEludGVnZXI+IGlkcyA9IEFycmF5cy5hc0xpc3QoMCwgMSwgMiwgMyk7CgkJCgkJLy8gRHVwZXMgYXJlIGFsbG93ZWQKCQlMaXN0PFN0cmluZz4gY29sb3JzID0gQXJyYXlzLmFzTGlzdCgiYmx1ZSIsICJ5ZWxsb3ciLCAicmVkIiwgImJsYWNrIik7CgkJCgkJLy8gTGlzdCBUeXBlcyBkbyBub3QgbmVlZCB0byBiZSB0aGUgc2FtZQoJCUxpc3Q8U3RyaW5nPiBjbG90aGVzID0gQXJyYXlzLmFzTGlzdCgic2hvZXMiLCAicGFudHMiLCAiYm9vdHMiLCAiY29hdCIpOwoJCQoJCVN5c3RlbS5vdXQucHJpbnRsbigiPT09PT09PSBCZWZvcmUgU29ydCA9PT09PT09PSIpOwoJCVN5c3RlbS5vdXQucHJpbnRsbihpZHMpOwoJCVN5c3RlbS5vdXQucHJpbnRsbihjb2xvcnMpOwoJCVN5c3RlbS5vdXQucHJpbnRsbihjbG90aGVzKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oKTsKCQkKCQlTeXN0ZW0ub3V0LnByaW50bG4oIj09PT09PT0gU29ydCBCeSBJRCA9PT09PT09PT0iKTsKCQljb25jdXJyZW50U29ydChpZHMsIGlkcywgY29sb3JzLCBjbG90aGVzKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oaWRzKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oY29sb3JzKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oY2xvdGhlcyk7CgkJU3lzdGVtLm91dC5wcmludGxuKCk7CgkJU3lzdGVtLm91dC5wcmludGxuKCk7CgkJCgkJU3lzdGVtLm91dC5wcmludGxuKCI9PT09PT09IFNvcnQgQnkgQ29sb3IgPT09PT09PT09Iik7CgkJY29uY3VycmVudFNvcnQoY29sb3JzLCBpZHMsIGNvbG9ycywgY2xvdGhlcyk7CgkJU3lzdGVtLm91dC5wcmludGxuKGlkcyk7CgkJU3lzdGVtLm91dC5wcmludGxuKGNvbG9ycyk7CgkJU3lzdGVtLm91dC5wcmludGxuKGNsb3RoZXMpOwoJCVN5c3RlbS5vdXQucHJpbnRsbigpOwoJCVN5c3RlbS5vdXQucHJpbnRsbigpOwoJCQoJCVN5c3RlbS5vdXQucHJpbnRsbigiPT09PT09PSBTb3J0IEJ5IENsb3RoZXMgPT09PT09PT09Iik7CgkJY29uY3VycmVudFNvcnQoY2xvdGhlcywgaWRzLCBjb2xvcnMsIGNsb3RoZXMpOwoJCVN5c3RlbS5vdXQucHJpbnRsbihpZHMpOwoJCVN5c3RlbS5vdXQucHJpbnRsbihjb2xvcnMpOwoJCVN5c3RlbS5vdXQucHJpbnRsbihjbG90aGVzKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oKTsKCX0KfQ==
======= Before Sort ========
[0, 1, 2, 3]
[blue, yellow, red, black]
[shoes, pants, boots, coat]
======= Sort By ID =========
[0, 1, 2, 3]
[blue, yellow, red, black]
[shoes, pants, boots, coat]
======= Sort By Color =========
[3, 0, 2, 1]
[black, blue, red, yellow]
[coat, shoes, boots, pants]
======= Sort By Clothes =========
[2, 3, 1, 0]
[red, black, yellow, blue]
[boots, coat, pants, shoes]