設定に応じて機能する可能性のある別のソリューションは、インスタンスを listB に格納するのではなく、listA のインデックスを格納することです。これは、次のように listA をカスタムのソート済みリスト内にラップすることで実行できます。
public static class SortedDependingList<E> extends AbstractList<E> implements List<E>{
private final List<E> dependingList;
private final List<Integer> indices;
public SortedDependingList(List<E> dependingList) {
super();
this.dependingList = dependingList;
indices = new ArrayList<>();
}
@Override
public boolean add(E e) {
int index = dependingList.indexOf(e);
if (index != -1) {
return addSorted(index);
}
return false;
}
/**
* Adds to this list the element of the depending list at the given
* original index.
* @param index The index of the element to add.
*
*/
public boolean addByIndex(int index){
if (index < 0 || index >= this.dependingList.size()) {
throw new IllegalArgumentException();
}
return addSorted(index);
}
/**
* Returns true if this list contains the element at the
* index of the depending list.
*/
public boolean containsIndex(int index){
int i = Collections.binarySearch(indices, index);
return i >= 0;
}
private boolean addSorted(int index){
int insertIndex = Collections.binarySearch(indices, index);
if (insertIndex < 0){
insertIndex = -insertIndex-1;
this.indices.add(insertIndex, index);
return true;
}
return false;
}
@Override
public E get(int index) {
return dependingList.get(indices.get(index));
}
@Override
public int size() {
return indices.size();
}
}
次に、このカスタム リストを次のように使用できます。
public static void main(String[] args) {
class SomeClass{
int index;
public SomeClass(int index) {
super();
this.index = index;
}
@Override
public String toString() {
return ""+index;
}
}
List<SomeClass> listA = new ArrayList<>();
for (int i = 0; i < 100; i++) {
listA.add(new SomeClass(i));
}
SortedDependingList<SomeClass> listB = new SortedDependingList<>(listA);
Random rand = new Random();
// add elements by index:
for (int i = 0; i < 5; i++) {
int index = rand.nextInt(listA.size());
listB.addByIndex(index);
}
System.out.println(listB);
// add elements by identity:
for (int i = 0; i < 5; i++) {
int index = rand.nextInt(listA.size());
SomeClass o = listA.get(index);
listB.add(o);
}
System.out.println(listB);
}
もちろん、このカスタム リストは、元のリストの要素が変更されない限り有効です。変更が可能な場合は、何らかの形で元のリストへの変更をリッスンし、カスタム リスト内のインデックスを更新する必要があります。
また、SortedDependingList は現在、listA からの要素を 2 回追加することを許可していないことに注意してください。この点では、実際には listA からの要素のセットのように機能します。これは通常、このような設定で必要なものだからです。
SortedDependingList に何かを追加するための推奨される方法は、要素のインデックスを既に知っていて、それを sortedList.addByIndex(index); を呼び出して追加することです。