/* 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
> key
= Arrays.
asList(4,
3,
1,
2,
1);
// Dupes are allowed
List
<String
> list1
= Arrays.
asList("Four",
"Three",
"One",
"Two",
"One*");
// List Types do not need to be the same
List
<Character
> list2
= Arrays.
asList('d',
'c',
'a',
'b',
'a');
System.
out.
println("======= Before Sort ========");
// Include key in the values parameter if you want it to be sorted too.
concurrentSort(key, key, list1, list2);
System.
out.
println("======= After Sort ========="); }
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5sYW5nLio7CmltcG9ydCBqYXZhLmlvLio7CgovKiBOYW1lIG9mIHRoZSBjbGFzcyBoYXMgdG8gYmUgIk1haW4iIG9ubHkgaWYgdGhlIGNsYXNzIGlzIHB1YmxpYy4gKi8KY2xhc3MgSWRlb25lewoJCglwdWJsaWMgc3RhdGljIDxUIGV4dGVuZHMgQ29tcGFyYWJsZTxUPj4gdm9pZCBjb25jdXJyZW50U29ydCggZmluYWwgTGlzdDxUPiBrZXksIExpc3Q8Pz4uLi4gbGlzdHMpewogICAgICAgIC8vIERvIHZhbGlkYXRpb24KICAgICAgICBpZihrZXkgPT0gbnVsbCB8fCBsaXN0cyA9PSBudWxsKQogICAgICAgIAl0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImtleSBjYW5ub3QgYmUgbnVsbC4iKTsKICAgICAgICAKICAgICAgICBmb3IoTGlzdDw/PiBsaXN0IDogbGlzdHMpCiAgICAgICAgCWlmKGxpc3Quc2l6ZSgpICE9IGtleS5zaXplKCkpCiAgICAgICAgCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJhbGwgbGlzdHMgbXVzdCBiZSB0aGUgc2FtZSBzaXplIik7CiAgICAgICAgCiAgICAgICAgLy8gTGlzdHMgYXJlIHNpemUgMCBvciAxLCBub3RoaW5nIHRvIHNvcnQKICAgICAgICBpZihrZXkuc2l6ZSgpIDwgMikKICAgICAgICAJcmV0dXJuOwogICAgICAgIAogICAgICAgIC8vIENyZWF0ZSBhIExpc3Qgb2YgaW5kaWNlcwoJCUxpc3Q8SW50ZWdlcj4gaW5kaWNlcyA9IG5ldyBBcnJheUxpc3Q8SW50ZWdlcj4oKTsKCQlmb3IoaW50IGkgPSAwOyBpIDwga2V5LnNpemUoKTsgaSsrKQoJCQlpbmRpY2VzLmFkZChpKTsKCiAgICAgICAgLy8gU29ydCB0aGUgaW5kaWNlcyBsaXN0IGJhc2VkIG9uIHRoZSBrZXkKCQlDb2xsZWN0aW9ucy5zb3J0KGluZGljZXMsIG5ldyBDb21wYXJhdG9yPEludGVnZXI+KCl7CgkJCUBPdmVycmlkZSBwdWJsaWMgaW50IGNvbXBhcmUoSW50ZWdlciBpLCBJbnRlZ2VyIGopIHsKCQkJCXJldHVybiBrZXkuZ2V0KGkpLmNvbXBhcmVUbyhrZXkuZ2V0KGopKTsKCQkJfQoJCX0pOwoJCQoJCU1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiBzd2FwTWFwID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgSW50ZWdlcj4oaW5kaWNlcy5zaXplKCkpOwoJCUxpc3Q8SW50ZWdlcj4gc3dhcEZyb20gPSBuZXcgQXJyYXlMaXN0PEludGVnZXI+KGluZGljZXMuc2l6ZSgpKSwKCQkJCQkgIHN3YXBUbyAgID0gbmV3IEFycmF5TGlzdDxJbnRlZ2VyPihpbmRpY2VzLnNpemUoKSk7CgogICAgICAgIC8vIGNyZWF0ZSBhIG1hcHBpbmcgdGhhdCBhbGxvd3Mgc29ydGluZyBvZiB0aGUgTGlzdCBieSBOIHN3YXBzLgoJCWZvcihpbnQgaSA9IDA7IGkgPCBrZXkuc2l6ZSgpOyBpKyspewoJCQlpbnQgayA9IGluZGljZXMuZ2V0KGkpOwoJCQl3aGlsZShpICE9IGsgJiYgc3dhcE1hcC5jb250YWluc0tleShrKSkKCQkJCWsgPSBzd2FwTWFwLmdldChrKTsKCQkJCgkJCXN3YXBGcm9tLmFkZChpKTsKCQkJc3dhcFRvLmFkZChrKTsKCQkJc3dhcE1hcC5wdXQoaSwgayk7CgkJfQoJCQogICAgICAgIC8vIHVzZSB0aGUgc3dhcCBvcmRlciB0byBzb3J0IGVhY2ggbGlzdCBieSBzd2FwcGluZyBlbGVtZW50cwoJCWZvcihMaXN0PD8+IGxpc3QgOiBsaXN0cykKCQkJZm9yKGludCBpID0gMDsgaSA8IGxpc3Quc2l6ZSgpOyBpKyspCgkJCQlDb2xsZWN0aW9ucy5zd2FwKGxpc3QsIHN3YXBGcm9tLmdldChpKSwgc3dhcFRvLmdldChpKSk7Cgl9CgkKCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluIChTdHJpbmdbXSBhcmdzKSB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbnsKCQlMaXN0PEludGVnZXI+IGtleSA9IEFycmF5cy5hc0xpc3QoNCwgMywgMSwgMiwgMSk7CgkJCgkJLy8gRHVwZXMgYXJlIGFsbG93ZWQKCQlMaXN0PFN0cmluZz4gbGlzdDEgPSBBcnJheXMuYXNMaXN0KCJGb3VyIiwgIlRocmVlIiwgIk9uZSIsICJUd28iLCAiT25lKiIpOwoJCQoJCS8vIExpc3QgVHlwZXMgZG8gbm90IG5lZWQgdG8gYmUgdGhlIHNhbWUKCQlMaXN0PENoYXJhY3Rlcj4gbGlzdDIgPSBBcnJheXMuYXNMaXN0KCdkJywgJ2MnLCAnYScsICdiJywgJ2EnKTsKCQkKCQlTeXN0ZW0ub3V0LnByaW50bG4oIj09PT09PT0gQmVmb3JlIFNvcnQgPT09PT09PT0iKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oa2V5KTsKCQlTeXN0ZW0ub3V0LnByaW50bG4obGlzdDEpOwoJCVN5c3RlbS5vdXQucHJpbnRsbihsaXN0Mik7CgkJU3lzdGVtLm91dC5wcmludGxuKCk7CgkJU3lzdGVtLm91dC5wcmludGxuKCk7CgkJCgkJLy8gSW5jbHVkZSBrZXkgaW4gdGhlIHZhbHVlcyBwYXJhbWV0ZXIgaWYgeW91IHdhbnQgaXQgdG8gYmUgc29ydGVkIHRvby4KCQljb25jdXJyZW50U29ydChrZXksIGtleSwgbGlzdDEsIGxpc3QyKTsKCQkKCQlTeXN0ZW0ub3V0LnByaW50bG4oIj09PT09PT0gQWZ0ZXIgU29ydCA9PT09PT09PT0iKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oa2V5KTsKCQlTeXN0ZW0ub3V0LnByaW50bG4obGlzdDEpOwoJCVN5c3RlbS5vdXQucHJpbnRsbihsaXN0Mik7Cgl9Cn0=
======= Before Sort ========
[4, 3, 1, 2, 1]
[Four, Three, One, Two, One*]
[d, c, a, b, a]
======= After Sort =========
[1, 1, 2, 3, 4]
[One, One*, Two, Three, Four]
[a, a, b, c, d]