Хотя это может работать, это далеко не лучшая практика.
Из документов SortedSet :
Обратите внимание, что порядок поддерживается отсортированным набором (независимо от того, предоставляется ли явный компаратор) должен быть согласован с equals, если отсортированный набор должен правильно реализовывать интерфейс Set .(См. Интерфейс Comparable или Comparator для точного определения соответствия с равными.) Это так, потому что интерфейс Set определен в терминах операции equals, но отсортированный наборвыполняет сравнение всех элементов, используя свой метод CompareTo (или сравнение), поэтому два элемента, которые этот метод считают равными, с точки зрения отсортированного набора, равны.Поведение отсортированного набора четко определено, даже если его порядок не совпадает с равенством;он просто не соблюдает общий контракт интерфейса Set.
Для объектов, которые реализуют Comparable
, всегда должна быть согласованность между методами equals()
, hashcode()
и compareTo()
.
Боюсь, что SortedSet
- это не то, что вам нужно, и Гуава MultiSet
не подойдет (потому что он не позволит вам независимо получать несколько одинаковых предметов).Я думаю, что вам нужно это SortedList
.Нет такого зверя, о котором я знаю (может быть, в коллекциях обыкновенных, но они немного унаследованы), поэтому я реализовал его для вас, используя ForwardingList от Guava в качестве базового класса.Вкратце: этот список делегирует почти все для ArrayList
, который он использует внутри, но он использует Collections.binarySearch()
в своем методе add()
, чтобы найти правильную позицию вставки, и он выбрасывает UnsupportedOperationException
во всех необязательных методах List
и ListIterator
интерфейсы, которые добавляют или устанавливают значения в данной позиции.
Конструкторы идентичны конструкторам ArrayList
, но для каждого из них также есть вторая версияс кастомом Comparator
.Если вы не используете пользовательский компаратор, ваши элементы списка должны реализовать Comparable
или RuntimeException
s будет происходить во время сортировки.
public class SortedArrayList<E> extends ForwardingList<E> implements
RandomAccess{
private final class ListIteratorImpl extends ForwardingListIterator<E>{
private final int start;
public ListIteratorImpl(final int start){
this.start = start;
}
@Override
public void set(E element){throw new UnsupportedOperationException();}
@Override
public void add(E element){throw new UnsupportedOperationException();}
@Override
protected ListIterator<E> delegate(){return inner.listIterator(start);};
}
private Comparator<? super E> comparator;
private List<E> inner;
public SortedArrayList(){this(null, null, null);}
@SuppressWarnings("unchecked")
private SortedArrayList(
final List<E> existing,
final Collection<? extends E> values,
final Comparator<? super E> comparator
){
this.comparator =
(Comparator<? super E>)
(comparator == null
? Ordering.natural()
: comparator );
inner = (
existing == null
? (values == null
? new ArrayList<E>(values)
: new ArrayList<E>()
)
: existing;
}
public SortedArrayList(final Collection<? extends E> c){
this(null, c, null);
}
public SortedArrayList(final Collection<? extends E> c,
final Comparator<? super E> comparator){
this(null, c, comparator);
}
public SortedArrayList(final Comparator<? super E> comparator){
this(null, null, comparator);
}
public SortedArrayList(final int initialCapacity){
this(new ArrayList<E>(initialCapacity), null, null);
}
public SortedArrayList(final int initialCapacity,
final Comparator<? super E> comparator){
this(new ArrayList<E>(initialCapacity), null, comparator);
}
@Override
public boolean add(final E e){
inner.add(
Math.abs(
Collections.binarySearch(inner, e, comparator)
) + 1,
e
);
return true;
}
@Override
public void add(int i, E e){throw new UnsupportedOperationException();}
@Override
public boolean addAll(final Collection<? extends E> collection){
return standardAddAll(collection);
}
@Override
public boolean addAll(int i,
Collection<? extends E> es){
throw new UnsupportedOperationException();
}
@Override
protected List<E> delegate(){ return inner; }
@Override
public List<E> subList(final int fromIndex, final int toIndex){
return new SortedArrayList<E>(
inner.subList(fromIndex, toIndex),
null,
comparator
);
}
@Override
public ListIterator<E> listIterator(){ return new ListIteratorImpl(0); }
@Override
public ListIterator<E> listIterator(final int index){
return new ListIteratorImpl(index);
}
@Override
public E set(int i, E e){ throw new UnsupportedOperationException(); }
}