Класс TreeSet наследуется от AbstractSet и реализует обобщенный интерфейс NavigableSet. Класс TreeSet также является обобщенным. Класс TreeSet физически хранит данные в упорядоченном виде в дереве. Данные внутри класса хранятся в классе TreeMap. Для того, чтобы класс можно было помещать в коолекцию TreeSet, он должен реализовать интерфейс Comparable, для того чтобы коллекция могла размещать их по порядку. От реализации метода compareTo(объект), зависит по убыванию или по возрастанию будут храниться элементы в коллекции. Коллекция не допускает хранение равных элементов. Для того, чтобы коллекция могла сравнивать два элемента на равенство, необходимо реализовать методы equals() и hashCode().
Интерфейс NavigableSet позволяет осуществлять поиск элемента в коллекции по точному совпадению, а также находить ближайшие элементы, расположенные справа и слева по порядку. Также интерфейс позволяет получать подмножества коллекции TreeSet, ограниченные справа или слева или двух сторон. Пример:
class Coordinate implements Comparable<Coordinate> { private int X; private int Y;
public Coordinate(int X, int Y) { this.X = X; this.Y = Y; }
@Override public String toString() { return "X: " + X + ", Y: " + Y; }
@Override public boolean equals(Object obj) { if(obj instanceof Coordinate){ Coordinate c = (Coordinate)obj; return c.X == this.X && c.Y == this.Y; }else { return super.equals(obj); } }
@Override public int hashCode() { int hash = 7; hash = 59 * hash + this.X; hash = 59 * hash + this.Y; return hash; }
//мы обязаны реализовать интерфейс Comparable, чтобы коллекция смогла располагать по порядку элементы коллекции @Override public int compareTo(Coordinate o) { return this.X - o.X; } }
void CollectionToTextArea(TreeSet<Coordinate> c, JTextArea ta){ for(Coordinate item: c){ta.append(item.toString() + "\n"); } ta.append("--------------------------------------------------" + "\n"); } void CoordinateToTextArea(Coordinate c, JTextArea ta, String comment){ if(c != null){ ta.append(comment + c.toString() + "\n"); } else{ ta.append("Объект null\n"); } } //выводим все содержимое очереди в текстовую область (при этом очередь очищается) void RemoveAllQueueElements(Queue <Coordinate> q){ Coordinate c = null; c = q.poll(); while(c != null) { jTextArea1.append("Удалили из очереди: " + c.toString() + "\n"); c = q.poll(); } } void IteratorToTextArea(Iterator <Coordinate> iter, JTextArea ta){ if (iter != null & ta != null){ while(iter.hasNext()){ ta.append(iter.next().toString() + "\n"); } } }; private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { //создаем коллекцию дерево TreeSet <Coordinate> ts = new TreeSet <Coordinate>(); //инициируем интерфейсную переменную NavigableSet <Coordinate> ns = ts; Random rnd = new Random(); int initValue = 0; for(int i = 0; i < 20; i ++){ initValue = rnd.nextInt(25); ns.add(new Coordinate(initValue, initValue)); } CollectionToTextArea(ts, jTextArea1); Coordinate e = new Coordinate(10, 10); Coordinate c1 = ns.ceiling(e); //методы по поиску элемента справа или слева CoordinateToTextArea(c1, jTextArea1, "ceiling('e') или наименьший объект справа или сам элемент: "); c1 = ns.floor(e); CoordinateToTextArea(c1, jTextArea1, "floor('e') или наибольший объект слева или сам элемент: "); c1 = ns.higher(e); CoordinateToTextArea(c1, jTextArea1, "higher('e') наименьший объект справа: "); c1 = ns.lower(e); CoordinateToTextArea(c1, jTextArea1, "lower('e') наибольший объект слева: "); //методы по извлечению элемента - элемент удаляется из коллекции //извлекаем первый элемент из дерева. В зависимости от направления сортировки будет извлечен //или минимальный или максимальный элемент коллекции c1 = ns.pollFirst(); CoordinateToTextArea(c1, jTextArea1, "pollFirst(): "); //извлекаем последний элемент дерева. В зависимости от направления сортировки будет извлечен //или максимальный или минимальный элемент коллекции c1 = ns.pollLast(); CoordinateToTextArea(c1, jTextArea1, "pollLast(): "); //выведем коллекция и проверим что крайние элементы удалены CollectionToTextArea(ts, jTextArea1); //методы по получению коллеции, состоящей из подмножества элементов //текущей коллекции //headSet() возвращает коллекцию, которая содержит элементы меньшие чем заданный элемнт "e" //то есть левую часть до заданного элемента коллекции NavigableSet <Coordinate> headset = ns.headSet(e, true); jTextArea1.append("headSet() коллекции" + "\n"); IteratorToTextArea(headset.iterator(), jTextArea1); //tailSet() возвращает коллекцию, которая состоит из элементов больших чем заданный элемент //то есть правую часть до заданного элемента коллекции NavigableSet <Coordinate> tailset = ns.tailSet(e, rootPaneCheckingEnabled); jTextArea1.append("tailSet() коллекции" + "\n"); IteratorToTextArea(tailset.iterator(), jTextArea1); //subSet() возвращет коллекцию состоящую из элементов обрезанную справа и слева заданными элементами NavigableSet <Coordinate> subset = ns.subSet(new Coordinate(5, 5), true, new Coordinate(15, 15), true); jTextArea1.append("subSet() коллекции" + "\n"); IteratorToTextArea(subset.iterator(), jTextArea1); //результирующие коллекции, которые получаются методами headSet(), tailSet(), subSet() //поддерживаются исходным набором, то есть копия данных не создается. Проверим это. headset.clear(); jTextArea1.append("после clear() headset" + "\n"); CollectionToTextArea(ts, jTextArea1); subset.clear(); jTextArea1.append("после clear() subset" + "\n"); CollectionToTextArea(ts, jTextArea1); }
|