diff --git a/MyTreeSet/.gitignore b/MyTreeSet/.gitignore
new file mode 100644
index 0000000..345e61a
--- /dev/null
+++ b/MyTreeSet/.gitignore
@@ -0,0 +1,49 @@
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff:
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/dictionaries
+
+# Sensitive or high-churn files:
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.xml
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+
+# Gradle:
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# CMake
+cmake-build-debug/
+
+# Mongo Explorer plugin:
+.idea/**/mongoSettings.xml
+
+## File-based project format:
+*.iws
+
+## Plugin-specific files:
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
diff --git a/MyTreeSet/.idea/compiler.xml b/MyTreeSet/.idea/compiler.xml
new file mode 100644
index 0000000..efede30
--- /dev/null
+++ b/MyTreeSet/.idea/compiler.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MyTreeSet/.idea/misc.xml b/MyTreeSet/.idea/misc.xml
new file mode 100644
index 0000000..e8942bd
--- /dev/null
+++ b/MyTreeSet/.idea/misc.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MyTreeSet/.idea/modules.xml b/MyTreeSet/.idea/modules.xml
new file mode 100644
index 0000000..0f5d373
--- /dev/null
+++ b/MyTreeSet/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MyTreeSet/MyTreeSet.iml b/MyTreeSet/MyTreeSet.iml
new file mode 100644
index 0000000..57f498f
--- /dev/null
+++ b/MyTreeSet/MyTreeSet.iml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MyTreeSet/pom.xml b/MyTreeSet/pom.xml
new file mode 100644
index 0000000..00d906d
--- /dev/null
+++ b/MyTreeSet/pom.xml
@@ -0,0 +1,36 @@
+
+
+ 4.0.0
+
+ ru,spbau.mit.kazakov.MyTreeSet
+ MyTreeSet
+ 1.0-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+
+ junit
+ junit
+ 4.8
+
+
+ org.jetbrains
+ annotations
+ 13.0
+
+
+
+
\ No newline at end of file
diff --git a/MyTreeSet/src/main/java/ru/spabu/mit/kazakov/TreeSet/HisTreeSet.java b/MyTreeSet/src/main/java/ru/spabu/mit/kazakov/TreeSet/HisTreeSet.java
new file mode 100644
index 0000000..2b2c8fe
--- /dev/null
+++ b/MyTreeSet/src/main/java/ru/spabu/mit/kazakov/TreeSet/HisTreeSet.java
@@ -0,0 +1,35 @@
+package ru.spabu.mit.kazakov.TreeSet;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeSet;
+
+public interface HisTreeSet extends Set {
+
+ /** {@link TreeSet#descendingIterator()} **/
+ Iterator descendingIterator();
+
+ /** {@link TreeSet#descendingSet()} **/
+ HisTreeSet descendingSet();
+
+
+ /** {@link TreeSet#first()} **/
+ E first();
+
+ /** {@link TreeSet#last()} **/
+ E last();
+
+
+ /** {@link TreeSet#lower(E)} **/
+ E lower(E e);
+
+ /** {@link TreeSet#floor(E)} **/
+ E floor(E e);
+
+
+ /** {@link TreeSet#ceiling(E)} **/
+ E ceiling(E e);
+
+ /** {@link TreeSet#higher(E)} **/
+ E higher(E e);
+}
diff --git a/MyTreeSet/src/main/java/ru/spabu/mit/kazakov/TreeSet/MyTreeSet.java b/MyTreeSet/src/main/java/ru/spabu/mit/kazakov/TreeSet/MyTreeSet.java
new file mode 100644
index 0000000..08f7a34
--- /dev/null
+++ b/MyTreeSet/src/main/java/ru/spabu/mit/kazakov/TreeSet/MyTreeSet.java
@@ -0,0 +1,464 @@
+package ru.spabu.mit.kazakov.TreeSet;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.AbstractSet;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * A generic set implemented using binary search tree.
+ *
+ * @param type of stored value
+ */
+public class MyTreeSet extends AbstractSet implements HisTreeSet {
+ private Comparator super E> comparator;
+ private int size = 0;
+ private Node root = null;
+ private boolean reverse = false;
+
+ /**
+ * Makes new myTreeSet containing values from specified myTreeSet, but with reversed order view of the values.
+ *
+ * @param originalSet specified myTreeSet
+ */
+ private MyTreeSet(@NotNull MyTreeSet originalSet) {
+ root = originalSet.root;
+ size = originalSet.size;
+ comparator = originalSet.comparator;
+ reverse = !originalSet.reverse;
+ }
+
+ /**
+ * Returns Node storing specified value.
+ *
+ * @param value specified value
+ * @return found Node if there is such Node, and null otherwise.
+ */
+ @Nullable
+ private Node find(@NotNull E value) {
+ Node current = root;
+
+ while (current != null) {
+ int compareResult = comparator.compare(current.value, value);
+ if (compareResult == 0) {
+ return current;
+ } else if (compareResult > 0) {
+ current = current.left;
+ } else {
+ current = current.right;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns lowest value.
+ *
+ * @return found value if there is such value, and null otherwise
+ */
+ @Nullable
+ private E normalOrderFirst() {
+ Node current = root;
+ if (current == null) {
+ return null;
+ }
+
+ while (current.left != null) {
+ current = current.left;
+ }
+
+ return current.value;
+ }
+
+ /**
+ * Returns highest value.
+ *
+ * @return found value if there is such value, and null otherwise
+ */
+ @Nullable
+ private E normalOrderLast() {
+ Node current = root;
+ if (current == null) {
+ return null;
+ }
+
+ while (current.right != null) {
+ current = current.right;
+ }
+
+ return current.value;
+ }
+
+ /**
+ * Returns the greatest value in this set strictly less than the specified value.
+ *
+ * @param value specified value
+ * @return found value if there is such value, and null otherwise
+ */
+ @Nullable
+ private E normalOrderLower(@NotNull E value) {
+ Node current = root;
+ if (current == null) {
+ return null;
+ }
+ E answer = null;
+
+ while (current != null) {
+ int compareResult = comparator.compare(current.value, value);
+ if (compareResult >= 0) {
+ current = current.left;
+ } else {
+ answer = current.value;
+ current = current.right;
+ }
+ }
+
+ return answer;
+ }
+
+ /**
+ * Returns the greatest value in this set less than or equal to the specified value,
+ *
+ * @param value specified value
+ * @return found value if there is such value, and null otherwise
+ */
+ @Nullable
+ private E normalOrderFloor(@NotNull E value) {
+ Node found = find(value);
+ return found != null ? found.value : normalOrderLower(value);
+ }
+
+ /**
+ * Returns the least value in this set greater than or equal to the specified value.
+ *
+ * @param value specified value
+ * @return found value if there is such value, and null otherwise
+ */
+ @Nullable
+ private E normalOrderCeiling(@NotNull E value) {
+ Node found = find(value);
+ return found != null ? found.value : normalOrderHigher(value);
+ }
+
+ /**
+ * Returns the least value in this set strictly greater than the given value,
+ *
+ * @param value specified value
+ * @return found value if there is such value, and null otherwise
+ */
+ @Nullable
+ private E normalOrderHigher(@NotNull E value) {
+ Node current = root;
+ E answer = null;
+
+ while (current != null) {
+ int compareResult = comparator.compare(current.value, value);
+ if (compareResult <= 0) {
+ current = current.right;
+ } else {
+ answer = current.value;
+ current = current.left;
+ }
+ }
+
+ return answer;
+ }
+
+ /**
+ * Initializes comparator for values ordering by specified comparator.
+ *
+ * @param comparator specified comparator
+ */
+ public MyTreeSet(@NotNull Comparator super E> comparator) {
+ this.comparator = comparator;
+ }
+
+ /**
+ * Initializes comparator for values ordering using value's comparability,
+ * therefore generic type must implements Comparable interface.
+ */
+ public MyTreeSet() {
+ comparator = (o1, o2) -> ((Comparable) o1).compareTo(o2);
+ }
+
+ /**
+ * Checks if there is a value equals to specified value.
+ *
+ * @param value to check
+ * @return true if there is such value, and false otherwise
+ */
+ @Override
+ public boolean contains(@NotNull Object value) {
+ return find((E) value) != null;
+ }
+
+ /**
+ * Adds new Node storing specified value to the tree.
+ *
+ * @param value to add
+ * @return false if there was specified value, and true otherwise
+ */
+ @Override
+ public boolean add(@NotNull E value) {
+ if (contains(value)) {
+ return false;
+ }
+ if (root == null) {
+ root = new Node(value);
+ size = 1;
+ return true;
+ }
+
+ Node current = root;
+ Node parent = null;
+ while (current != null) {
+ parent = current;
+ int compareResult = comparator.compare(current.value, value);
+ if (compareResult > 0) {
+ current = current.left;
+ } else if (compareResult < 0) {
+ current = current.right;
+ }
+
+ }
+
+ int compareResult = comparator.compare(parent.value, value);
+ if (compareResult < 0) {
+ parent.right = new Node(value);
+ } else if (compareResult > 0) {
+ parent.left = new Node(value);
+ }
+
+ size++;
+ return true;
+ }
+
+ /**
+ * Removes Node storing specified value from tree.
+ *
+ * @param value to remove
+ * @return true if there was specified value, and false otherwise
+ */
+ @Override
+ public boolean remove(@NotNull Object value) {
+ if (!contains(value)) {
+ return false;
+ }
+ size--;
+
+ Node current = root;
+ Node parent = null;
+ int compareResult;
+ while ((compareResult = comparator.compare(current.value, (E) value)) != 0) {
+ parent = current;
+ if (compareResult > 0) {
+ current = current.left;
+ } else {
+ current = current.right;
+ }
+ }
+
+ boolean isLeftChild = parent != null && parent.left == current;
+ if (parent != null) {
+ if (current.left == null) {
+ if (isLeftChild) {
+ parent.left = current.right;
+ return true;
+ } else {
+ parent.right = current.right;
+ return true;
+ }
+ } else if (current.right == null) {
+ if (isLeftChild) {
+ parent.left = current.left;
+ return true;
+ } else {
+ parent.right = current.left;
+ return true;
+ }
+ }
+ } else {
+ if (current.left == null) {
+ root = current.right;
+ return true;
+ } else if (current.right == null) {
+ root = current.left;
+ return true;
+ }
+ }
+
+ E nextValue = normalOrderHigher(current.value);
+ remove(nextValue);
+ current.value = nextValue;
+
+ return true;
+ }
+
+ /**
+ * Returns an iterator over the values in this set in descending order.
+ */
+ @NotNull
+ public Iterator descendingIterator() {
+ return descendingSet().iterator();
+ }
+
+ /**
+ * Returns a reverse order view of the values contained in this set.
+ */
+ public MyTreeSet descendingSet() {
+ return new MyTreeSet<>(this);
+ }
+
+ /**
+ * Returns lowest value if order isn't reversed, and highest value otherwise.
+ *
+ * @return found value if there is such value, and null otherwise
+ */
+ @Nullable
+ public E first() {
+ if (reverse) {
+ return normalOrderLast();
+ } else {
+ return normalOrderFirst();
+ }
+ }
+
+ /**
+ * Returns highest value if order isn't reversed, and lowest value otherwise.
+ *
+ * @return found value if there is such value, and null otherwise
+ */
+ @Nullable
+ public E last() {
+ if (reverse) {
+ return normalOrderFirst();
+ } else {
+ return normalOrderLast();
+ }
+ }
+
+ /**
+ * Returns the greatest value in this set strictly less than the specified value if order isn't reversed, and
+ * the least value in this set strictly greater than the specified value otherwise.
+ *
+ * @param value specified value
+ * @return found value if there is such value, and null otherwise
+ */
+ @Nullable
+ public E lower(@NotNull E value) {
+ if (reverse) {
+ return normalOrderHigher(value);
+ } else {
+ return normalOrderLower(value);
+ }
+ }
+
+ /**
+ * Returns the greatest value in this set less than or equal to the specified value if order isn't reversed, and
+ * the least value in this set greater than or equal to the specified value otherwise.
+ *
+ * @param value specified value
+ * @return found value if there is such value, and null otherwise
+ */
+ @Nullable
+ public E floor(@NotNull E value) {
+ if (reverse) {
+ return normalOrderCeiling(value);
+ } else {
+ return normalOrderFloor(value);
+ }
+ }
+
+ /**
+ * Returns the least value in this set greater than or equal to the specified value if order isn't reversed, and
+ * the greatest value in this set less than or equal to the specified value otherwise.
+ *
+ * @param value specified value
+ * @return found value if there is such value, and null otherwise
+ */
+ @Nullable
+ public E ceiling(@NotNull E value) {
+ if (reverse) {
+ return normalOrderLower(value);
+ } else {
+ return normalOrderCeiling(value);
+ }
+ }
+
+ /**
+ * Returns the least value in this set strictly greater than the given value if order isn't reversed, and
+ * the greatest value in this set strictly less than the specified value otherwise.
+ *
+ * @param value specified value
+ * @return found value if there is such value, and null otherwise
+ */
+ @Nullable
+ public E higher(@NotNull E value) {
+ if (reverse) {
+ return normalOrderLower(value);
+ } else {
+ return normalOrderHigher(value);
+ }
+ }
+
+ /**
+ * Returns an iterator over the values in this set.
+ */
+ @NotNull
+ public Iterator iterator() {
+ return new MyTreeSetIterator();
+ }
+
+ /**
+ * Returns number of stored values in the tree.
+ */
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Node for binary search tree. Stores left, right children and value.
+ */
+ private class Node {
+ private Node left = null;
+ private Node right = null;
+ private E value;
+
+ /**
+ * Initializes stored value with specified value.
+ *
+ * @param value specified value
+ */
+ private Node(@NotNull E value) {
+ this.value = value;
+ }
+
+ }
+
+ /**
+ * Iterator for ru.spabu.mit.kazakov.TreeSet.MyTreeSet.
+ */
+ private class MyTreeSetIterator implements Iterator {
+ private E next = first();
+
+ @Override
+ public boolean hasNext() {
+ return next != null;
+ }
+
+ @Override
+ public E next() {
+ if (next == null) {
+ throw new NoSuchElementException();
+ }
+
+ E prev = next;
+ next = higher(next);
+ return prev;
+ }
+ }
+}
diff --git a/MyTreeSet/src/test/java/MyTreeSetTest.java b/MyTreeSet/src/test/java/MyTreeSetTest.java
new file mode 100644
index 0000000..acc6aaa
--- /dev/null
+++ b/MyTreeSet/src/test/java/MyTreeSetTest.java
@@ -0,0 +1,395 @@
+import org.junit.Test;
+import ru.spabu.mit.kazakov.TreeSet.MyTreeSet;
+
+import java.util.*;
+import java.util.concurrent.ThreadLocalRandom;
+
+import static org.junit.Assert.*;
+
+public class MyTreeSetTest {
+ @Test
+ public void testConstructor() {
+ new MyTreeSet();
+ }
+
+ @Test
+ public void testConstructorWithComparator() {
+ new MyTreeSet((o1, o2) -> -1 * o1.compareTo(o2));
+ }
+
+ @Test
+ public void testAddReturnTrue() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ assertTrue(mySet.add(1L));
+ }
+
+ @Test
+ public void testAddReturnFalse() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.add(1L);
+
+ assertFalse(mySet.add(1L));
+ }
+
+ @Test
+ public void testAdd() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.add(17L);
+ mySet.add(13L);
+ mySet.add(2L);
+
+ assertArrayEquals(new Long[]{2L, 13L, 17L}, mySet.toArray());
+ }
+
+ @Test
+ public void testAddTheSame() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.add(17L);
+ mySet.add(13L);
+ mySet.add(2L);
+ mySet.add(13L);
+
+ assertArrayEquals(new Long[]{2L, 13L, 17L}, mySet.toArray());
+ }
+
+ @Test
+ public void testAddRandom() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ TreeSet random = new TreeSet<>();
+
+ for (int i = 0; i < 100; i++) {
+ Integer valueToAdd = ThreadLocalRandom.current().nextInt(0, 30);
+ random.add(valueToAdd);
+ mySet.add(valueToAdd);
+ }
+
+ assertArrayEquals(random.toArray(), mySet.toArray());
+ }
+
+ @Test
+ public void testRemoveReturnTrue() {
+ MyTreeSet mySet = new MyTreeSet<>((o1, o2) -> -1 * o1.compareTo(o2));
+ mySet.add((char) 1);
+
+ assertTrue(mySet.remove((char) 1));
+ }
+
+ @Test
+ public void testRemoveReturnFalse() {
+ MyTreeSet mySet = new MyTreeSet<>((o1, o2) -> -1 * o1.compareTo(o2));
+ mySet.add((char) 1);
+
+ assertFalse(mySet.remove((char) 2));
+ }
+
+ @Test
+ public void testRemove() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.add('a');
+ mySet.add('z');
+ mySet.add('v');
+ mySet.add('t');
+ mySet.remove('t');
+ mySet.remove('a');
+
+ assertArrayEquals(new Character[]{'v', 'z'}, mySet.toArray());
+ }
+
+ @Test
+ public void testRemoveTheSame() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.add('a');
+ mySet.add('z');
+ mySet.add('v');
+ mySet.add('t');
+ mySet.remove('t');
+ mySet.remove('a');
+ mySet.remove('t');
+
+ assertArrayEquals(new Character[]{'v', 'z'}, mySet.toArray());
+ }
+
+ @Test
+ public void testSizeEmpty() {
+ assertEquals(0, new MyTreeSet().size());
+ }
+
+ @Test
+ public void testSizeAdd() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.add(5);
+ mySet.add(2);
+
+ assertEquals(2, mySet.size());
+ }
+
+ @Test
+ public void testSizeAddTheSame() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.add(2);
+ mySet.add(2);
+
+ assertEquals(1, mySet.size());
+ }
+
+ @Test
+ public void testSizeRemove() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.add(5);
+ mySet.add(2);
+ mySet.remove(2);
+
+ assertEquals(1, mySet.size());
+ }
+
+ @Test
+ public void testSizeRemoveTheSame() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.add(5);
+ mySet.add(2);
+ mySet.remove(2);
+ mySet.remove(2);
+
+ assertEquals(1, mySet.size());
+ }
+
+ @Test
+ public void testSizeOneHundred() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ for (int i = 0; i < 100; i++) {
+ mySet.add(i);
+ }
+
+ assertEquals(100, mySet.size());
+ }
+
+ @Test
+ public void testContainsNotExisting() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.add((byte) 1);
+
+ assertFalse(mySet.contains((byte) 2));
+ }
+
+ @Test
+ public void testContainsAdd() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.add((byte) 55);
+
+ assertTrue(mySet.contains((byte) 55));
+ }
+
+ @Test
+ public void testContainsRemove() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.add((byte) 111);
+ mySet.remove((byte) 111);
+
+ assertFalse(mySet.contains((byte) 111));
+ }
+
+ @Test
+ public void testFirstEmptySet() {
+ assertNull(new MyTreeSet((o1, o2) -> -1 * o1.compareTo(o2)).first());
+ }
+
+ @Test
+ public void testFirst() {
+ MyTreeSet mySet = new MyTreeSet<>((o1, o2) -> -1 * o1.compareTo(o2));
+ mySet.addAll(Arrays.asList((short) 100, (short) -2, (short) -33, (short) 4));
+ assertEquals(100, mySet.first().shortValue());
+ }
+
+ @Test
+ public void testFirstDescendingSet() {
+ MyTreeSet mySet = new MyTreeSet<>((o1, o2) -> -1 * o1.compareTo(o2));
+ mySet.addAll(Arrays.asList((short) 100, (short) -2, (short) -33, (short) 4));
+ assertEquals(-33, mySet.descendingSet().first().shortValue());
+ }
+
+ @Test
+ public void testLastEmptySet() {
+ assertNull(new MyTreeSet((o1, o2) -> -1 * o1.compareTo(o2)).last());
+ }
+
+ @Test
+ public void testLast() {
+ MyTreeSet mySet = new MyTreeSet<>((o1, o2) -> -1 * o1.compareTo(o2));
+ mySet.addAll(Arrays.asList((short) 100, (short) -2, (short) -33, (short) 4));
+ assertEquals(-33, mySet.last().shortValue());
+ }
+
+ @Test
+ public void testLastDescendingSet() {
+ MyTreeSet mySet = new MyTreeSet<>((o1, o2) -> -1 * o1.compareTo(o2));
+ mySet.addAll(Arrays.asList((short) 100, (short) -2, (short) -33, (short) 4));
+ assertEquals(100, mySet.descendingSet().last().shortValue());
+ }
+
+ @Test
+ public void testEmptyHigher() {
+ assertNull(new MyTreeSet().higher((short) 15));
+ }
+
+ @Test
+ public void testNotExistingHigher() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 15, (short) 10));
+ assertNull(mySet.higher((short) 15));
+ }
+
+ @Test
+ public void testNotExistingHigherDescendingSet() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 15, (short) 10));
+ assertNull(mySet.descendingSet().higher((short) 1));
+ }
+
+ @Test
+ public void testHigher() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 15, (short) 10));
+ assertEquals(10, mySet.higher((short) 3).shortValue());
+ }
+
+ @Test
+ public void testHigherDescendingSet() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 15, (short) 10));
+ assertEquals(3, mySet.descendingSet().higher((short) 10).shortValue());
+ }
+
+ @Test
+ public void testEmptyLower() {
+ assertNull(new MyTreeSet().lower((short) 15));
+ }
+
+ @Test
+ public void testNotExistingLower() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 15, (short) 10));
+ assertNull(mySet.lower((short) 1));
+ }
+
+ @Test
+ public void testNotExistingLowerDescendingSet() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 15, (short) 10));
+ assertNull(mySet.descendingSet().lower((short) 15));
+ }
+
+ @Test
+ public void testLower() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 15, (short) 10));
+ assertEquals(1, mySet.lower((short) 2).shortValue());
+ }
+
+ @Test
+ public void testLowerDescendingSet() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 15, (short) 10));
+ assertEquals(10, mySet.descendingSet().lower((short) 4).shortValue());
+ }
+
+ @Test
+ public void testEmptyFloor() {
+ assertNull(new MyTreeSet<>().floor((short) 15));
+ }
+
+ @Test
+ public void testNotExistingFloor() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 15, (short) 10));
+ assertNull(mySet.floor((short) 0));
+ }
+
+ @Test
+ public void testNotExistingFloorDescendingSet() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 15, (short) 10));
+ assertNull(mySet.descendingSet().floor((short) 17));
+ }
+
+ @Test
+ public void testFloor() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 15, (short) 10));
+ assertEquals(15, mySet.floor((short) 15).shortValue());
+ }
+
+ @Test
+ public void testFloorDescendingSet() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 15, (short) 10));
+ assertEquals(10, mySet.descendingSet().lower((short) 4).shortValue());
+ }
+
+ @Test
+ public void testEmptyCeiling() {
+ assertNull(new MyTreeSet<>().ceiling((short) 15));
+ }
+
+ @Test
+ public void testNotExistingCeiling() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 15, (short) 10));
+ assertNull(mySet.ceiling((short) 100));
+ }
+
+ @Test
+ public void testNotExistingCeilingDescendingSet() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 15, (short) 10));
+ assertNull(mySet.descendingSet().ceiling((short) -17));
+ }
+
+ @Test
+ public void testCeiling() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 15, (short) 10));
+ assertEquals(15, mySet.ceiling((short) 15).shortValue());
+ }
+
+ @Test
+ public void testCeilingDescendingSet() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 15, (short) 10));
+ assertEquals(3, mySet.descendingSet().ceiling((short) 4).shortValue());
+ }
+
+ @Test(expected = NoSuchElementException.class)
+ public void testIteratorThrowsNoSuchElementException() {
+ Iterator iterator = new MyTreeSet().iterator();
+ iterator.next();
+ }
+
+ @Test
+ public void testIterator() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 2, (short) 0));
+ Iterator iterator = mySet.iterator();
+
+ for (byte i = 0; i < 4; i++) {
+ assertTrue(iterator.hasNext());
+ assertEquals(i, iterator.next().byteValue());
+ }
+
+ assertFalse(iterator.hasNext());
+ }
+
+ @Test
+ public void testDescendingIterator() {
+ MyTreeSet mySet = new MyTreeSet<>();
+ mySet.addAll(Arrays.asList((short) 1, (short) 3, (short) 2, (short) 0));
+ Iterator iterator = mySet.descendingIterator();
+
+ for (byte i = 3; i >= 0; i--) {
+ assertTrue(iterator.hasNext());
+ assertEquals(i, iterator.next().byteValue());
+ }
+
+ assertFalse(iterator.hasNext());
+ }
+
+}
\ No newline at end of file