From ac035870f24d92567250b7f23e545ce540e6b7a3 Mon Sep 17 00:00:00 2001 From: Frolov Georgy Date: Sat, 4 Dec 2021 17:03:39 +0300 Subject: [PATCH 1/2] Added LinkedList and HashMap custom classes --- .gitignore | 3 + src/GarriksHashMap.java | 144 ++++++++++++++++++++++++ src/GarriksLinkedList.java | 175 +++++++++++++++++++++++++++++ src/GarriksLinkedListIterator.java | 25 +++++ src/GarriksNode.java | 58 ++++++++++ src/README.md | 47 ++++++++ src/RunHashMap.java | 110 ++++++++++++++++++ src/RunLinkedList.java | 156 +++++++++++++++++++++++++ 8 files changed, 718 insertions(+) create mode 100644 src/GarriksHashMap.java create mode 100644 src/GarriksLinkedList.java create mode 100644 src/GarriksLinkedListIterator.java create mode 100644 src/GarriksNode.java create mode 100644 src/README.md create mode 100644 src/RunHashMap.java create mode 100644 src/RunLinkedList.java diff --git a/.gitignore b/.gitignore index a1c2a23..4570fca 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,6 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* +/.idea/ +/JavaCourse_HW_1_9.iml +/out/ diff --git a/src/GarriksHashMap.java b/src/GarriksHashMap.java new file mode 100644 index 0000000..06d77ff --- /dev/null +++ b/src/GarriksHashMap.java @@ -0,0 +1,144 @@ +import java.util.Collection; + +public class GarriksHashMap implements HashMapInterface { + private GarriksLinkedList[] array; + private int capacity; + private double loadFactor; + + public GarriksHashMap() { + this.array = new GarriksLinkedList[16]; + this.capacity = 16; + this.loadFactor = 0.75; + } + + @Override + public int size() { + int size = 0; + for (GarriksLinkedList list : array) { + if (list != null) { + size += list.size(); + } + } + return size; + } + + @Override + public boolean isEmpty() { + return size() == 0; + } + + @Override + public boolean containsKey(Object key) { + int bucket = getBucketNum(key); + if (array[bucket] != null) { + for (GarriksNode node : array[bucket]) { + if (node.getKey().equals(key)) { + return true; + } + } + } + return false; + } + + + @Override + public boolean containsValue(Object value) { + for (GarriksLinkedList bucket : array) { + if (bucket != null) { + for (GarriksNode node : bucket) { + if (node.getItem().equals(value)) { + return true; + } + } + } + } + return false; + } + + // хз как делать + @Override + public Collection values() { + return null; + } + + @Override + public V put(K key, V value) { + checkSize(); + int bucket = getBucketNum(key); + createBucket(bucket); + array[bucket].addMap(key, value); + return value; + } + + @Override + public V get(Object key) { + int bucket = getBucketNum(key); + return array[bucket].getByKey(key); + } + + @Override + public V remove(Object key) { + checkSize(); + int bucket = getBucketNum(key); + V result = array[bucket].getByKey(key); + array[bucket].remove(result); + if (array[bucket].size() == 0) { + array[bucket] = null; + } + return result; + } + + @Override + public void clear() { + array = new GarriksLinkedList[16]; + capacity = 16; + loadFactor = 0.75; + } + + private int getBucketNum(Object key) { + return Math.abs(key.hashCode() % capacity); + } + + private void checkSize() { + if (size() > loadFactor * capacity) { + capacity *= 2; + replacementArray(); + } + if (size() > 13 && capacity > size() * loadFactor / 2) { + capacity /= 2; + replacementArray(); + } + + + } + + private void replacementArray() { + GarriksLinkedList[] newArray = new GarriksLinkedList[capacity]; + for (GarriksLinkedList bucket : array) { + if (bucket != null) { + for (GarriksNode node : bucket) { + if (newArray[getBucketNum(node.getKey())] == null) { + newArray[getBucketNum(node.getKey())] = new GarriksLinkedList<>(); + } + newArray[getBucketNum(node.getKey())].addMap(node.getKey(), node.getItem()); + } + } + } + array = newArray; + } + + private void createBucket(int index) { + if (array[index] == null) { + array[index] = new GarriksLinkedList<>(); + } + } + + @Override + public String toString() { + String result = ""; + for (GarriksLinkedList bucket : array) { + result = result + bucket + "\n"; + } + return result; + } +} diff --git a/src/GarriksLinkedList.java b/src/GarriksLinkedList.java new file mode 100644 index 0000000..570b814 --- /dev/null +++ b/src/GarriksLinkedList.java @@ -0,0 +1,175 @@ +import java.util.Iterator; + +public class GarriksLinkedList implements LinkedListInterface, Iterable> { + + + private final GarriksNode head; + private final GarriksNode tail; + private int len; + + public GarriksLinkedList() { + this.head = new GarriksNode<>(null, null, null); + this.tail = new GarriksNode<>(null, null, head); + this.head.setNext(this.tail); + this.len = 0; + } + + public GarriksNode getHead() { + return head; + } + + @Override + public int size() { + return len; + } + + @Override + public boolean isEmpty() { + return len == 0; + } + + @Override + public boolean contains(Object o) { +// Возможно ли каким-либо образом подобное реализовать? +// if (o.getClass() != E) { +// return false; +// } + + GarriksNode currNode = head.getNext(); + while (currNode.getItem() != null && !currNode.getItem().equals(o)) { + currNode = currNode.getNext(); + } + return currNode.getItem() != null && currNode.getItem().equals(o); + } + + @Override + public boolean add(E o) { + GarriksNode prevNode = tail.getPrev(); + GarriksNode newNode = new GarriksNode<>(o, tail, prevNode); + prevNode.setNext(newNode); + tail.setPrev(newNode); + len++; + return true; + } + + @Override + public void add(int index, E element) { + GarriksNode currNode = index == 0 ? head : getNode(index - 1); + GarriksNode nextNode = currNode.getNext(); + GarriksNode newNode = new GarriksNode<>(element, nextNode, currNode); + currNode.setNext(newNode); + nextNode.setPrev(newNode); + len++; + } + + // метод для добавления узла с ключом + public void addMap(T key, E element) { + for (GarriksNode node : this) { + if (node.getKey().equals(key)) { + node.setItem(element); + node.setKey(key); + return; + } + } + GarriksNode prevNode = tail.getPrev(); + GarriksNode newNode = new GarriksNode<>(element, key, tail, prevNode); + prevNode.setNext(newNode); + tail.setPrev(newNode); + len++; + } + + @Override + public E get(int index) { + return getNode(index).getItem(); + } + + // получение элемента по ключу + public E getByKey(Object key) { + for (GarriksNode node : this) { + if (node.getKey().equals(key)) { + return node.getItem(); + } + } + return null; + } + + @Override + public int indexOf(Object o) { + GarriksNode currNode = head; + for (int i = 0; i < len; i++) { + currNode = currNode.getNext(); + if (o.equals(currNode.getItem())) { + return i; + } + } + return -1; + } + + @Override + public E set(int index, E element) { + getNode(index).setItem(element); + return element; + } + + @Override + public E remove(int index) { + GarriksNode currItem = getNode(index); + GarriksNode prevItem = currItem.getPrev(); + GarriksNode nextItem = currItem.getNext(); + prevItem.setNext(nextItem); + nextItem.setPrev(prevItem); + len--; + return currItem.getItem(); + } + + @Override + public boolean remove(Object o) { + GarriksNode currItem = getNode(indexOf(o)); + GarriksNode prevItem = currItem.getPrev(); + GarriksNode nextItem = currItem.getNext(); + prevItem.setNext(nextItem); + nextItem.setPrev(prevItem); + len--; + return true; + } + + @Override + public void clear() { + // я же правильно понимаю, что при отсутствии ссылок на объекты (в данном случае ссылок на узлы) эти объекты удаляются из памяти, поэтому можно просто создань новые голову и хвост + head.setNext(tail); + tail.setPrev(head); + len = 0; + } + + public Iterator> iterator() { + return new GarriksLinkedListIterator<>(this); + } + + private GarriksNode getNode(int index) { + if (index >= len || index < 0) { + throw new IndexOutOfBoundsException(); + } + GarriksNode currNode = head; + for (int i = 0; i < index + 1; i++) { + currNode = currNode.getNext(); + } + return currNode; + } + + public T getKey(int index) { + return getNode(index).getKey(); + } + + @Override + public String toString() { + GarriksNode currElem = head; + String result = "head -> "; + for (int i = 0; i < len; i++) { + currElem = currElem.getNext(); + result = new String(result + currElem.getItem() + " -> "); + } + result = new String(result + "tail"); + return result; + } + +} diff --git a/src/GarriksLinkedListIterator.java b/src/GarriksLinkedListIterator.java new file mode 100644 index 0000000..3dc6bc4 --- /dev/null +++ b/src/GarriksLinkedListIterator.java @@ -0,0 +1,25 @@ +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class GarriksLinkedListIterator implements Iterator> { + + private GarriksNode currElem; + + public GarriksLinkedListIterator(GarriksLinkedList arr) { + this.currElem = arr.getHead(); + } + + @Override + public boolean hasNext() { + return currElem.getNext().getItem() != null; + } + + @Override + public GarriksNode next() { + if (!this.hasNext()) { + throw new NoSuchElementException("Garriks iterator can't see more elements :)"); + } + currElem = currElem.getNext(); + return currElem; + } +} diff --git a/src/GarriksNode.java b/src/GarriksNode.java new file mode 100644 index 0000000..9969b66 --- /dev/null +++ b/src/GarriksNode.java @@ -0,0 +1,58 @@ +import java.util.Iterator; + +public class GarriksNode { + private E item; + private T key; + private GarriksNode next; + private GarriksNode prev; + + public GarriksNode(E item, GarriksNode next, GarriksNode prev) { + this.item = item; + this.next = next; + this.prev = prev; + } + + public GarriksNode(E item, T key, GarriksNode next, GarriksNode prev) { + this.item = item; + this.key = key; + this.next = next; + this.prev = prev; + } + + public GarriksNode getNext() { + return next; + } + + public void setNext(GarriksNode newNext) { + next = newNext; + } + + public E getItem() { + return item; + } + + public void setItem(E newItem) { + item = newItem; + } + + public GarriksNode getPrev() { + return prev; + } + + public void setPrev(GarriksNode prev) { + this.prev = prev; + } + + public T getKey() { + return key; + } + + public void setKey(T key) { + this.key = key; + } + + public String toString() { + return (String) item; + } + +} diff --git a/src/README.md b/src/README.md new file mode 100644 index 0000000..538e692 --- /dev/null +++ b/src/README.md @@ -0,0 +1,47 @@ +| Метод LinkedList | Время работы, мс | +|----------------------|------------------| +| garriksList.add | 131 | +| linkedList.add | 126 | +| garriksList.getHead | 9 | +| linkedList.getFirst | 2 | +| garriksList.size | 10 | +| linkedList.size | 2 | +| garriksList.isEmpty | 6 | +| linkedList.isEmpty | 10 | +| garriksList.contains | 17604 | +| linkedList.contains | 10095 | +| garriksList.get | 15524 | +| linkedList.get | 7033 | +| garriksList.indexOf | 17704 | +| linkedList.indexOf | 10158 | +| garriksList.isEmpty | 6 | +| linkedList.isEmpty | 10 | +| garriksList.set | 17506 | +| linkedList.set | 7638 | +| garriksList.remove | 178 | +| linkedList.remove | 108 | +| garriksList.clear | 0 | +| linkedList.clear | 11 | +| garriksList.add | 8812 | +| linkedList.add | 6 | + + +| Метод HashMap | Время работы, мс | +|--------------------------|------------------| +| garriksMap.put | 5101 | +| hashMap.put | 8 | +| garriksMap.size | 1375 | +| hashMap.size | 10 | +| garriksMap.isEmpty | 1374 | +| hashMap.isEmpty | 11 | +| garriksMap.containsKey | 28 | +| hashMap.containsKey | 17 | +| garriksMap.containsValue | 201 | +| hashMap.containsValue | 260 | +| garriksMap.get | 2 | +| hashMap.get | 1 | +| garriksMap.remove | 4716 | +| hashMap.remove | 8 | +| garriksMap.clear | 0 | +| hashMap.clear | 0 | + diff --git a/src/RunHashMap.java b/src/RunHashMap.java new file mode 100644 index 0000000..20710b4 --- /dev/null +++ b/src/RunHashMap.java @@ -0,0 +1,110 @@ +import java.util.HashMap; +import java.util.LinkedList; + +public class RunHashMap { + private static void endTime(double start, String funcName) { + System.out.printf("%s %.0f %s", funcName, (System.currentTimeMillis() - start), "\n\n"); + } + + public static void main(String[] args) { + GarriksHashMap garriksMap = new GarriksHashMap<>(); + HashMap hashMap = new HashMap<>(); + + double start = System.currentTimeMillis(); + for (int i = 0; i < 10000; i++) { + garriksMap.put(String.format("sus%d", i), i); + } + endTime(start, "garriksMap.put "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 10000; i++) { + hashMap.put(String.format("sus%d", i), i); + } + endTime(start, "hashMap.put "); + + + start = System.currentTimeMillis(); + for (int i = 0; i < 1000000; i++) { + garriksMap.size(); + } + endTime(start, "garriksMap.size "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 1000000; i++) { + hashMap.size(); + } + endTime(start, "hashMap.size "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 1000000; i++) { + garriksMap.isEmpty(); + } + endTime(start, "garriksMap.isEmpty "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 1000000; i++) { + hashMap.isEmpty(); + } + endTime(start, "hashMap.isEmpty "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 10000; i++) { + garriksMap.containsKey(String.format("sus%d", i)); + } + endTime(start, "garriksMap.containsKey "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 10000; i++) { + hashMap.containsKey(String.format("sus%d", i)); + } + endTime(start, "hashMap.containsKey "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 10000; i++) { + garriksMap.containsValue(i); + } + endTime(start, "garriksMap.containsValue "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 10000; i++) { + hashMap.containsValue(i); + } + endTime(start, "hashMap.containsValue "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 1000; i++) { + garriksMap.get(String.format("sus%d", i)); + } + endTime(start, "garriksMap.get "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 1000; i++) { + hashMap.get(String.format("sus%d", i)); + } + endTime(start, "hashMap.get "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 10000; i++) { + garriksMap.remove(String.format("sus%d", i)); + } + endTime(start, "garriksMap.remove "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 10000; i++) { + hashMap.remove(String.format("sus%d", i)); + } + endTime(start, "hashMap.remove "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 1000; i++) { + garriksMap.clear(); + } + endTime(start, "garriksMap.clear "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 1000; i++) { + hashMap.clear(); + } + endTime(start, "hashMap.clear "); + } +} diff --git a/src/RunLinkedList.java b/src/RunLinkedList.java new file mode 100644 index 0000000..9b5cf80 --- /dev/null +++ b/src/RunLinkedList.java @@ -0,0 +1,156 @@ +import java.util.LinkedList; + +public class RunLinkedList { + private static void endTime(double start, String funcName) { + System.out.printf("%s %.0f %s", funcName, (System.currentTimeMillis() - start), "\n\n"); + } + + public static void main(String[] args) { + GarriksLinkedList garriksList = new GarriksLinkedList<>(); + LinkedList linkedList = new LinkedList<>(); + + double start = System.currentTimeMillis(); + for (int i = 0; i < 1000000; i++) { + garriksList.add(i); + } + endTime(start, "garriksList.add "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 1000000; i++) { + linkedList.add(i); + } + endTime(start, "linkedList.add "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 1000000; i++) { + garriksList.getHead(); + } + endTime(start, "garriksList.getHead "); + + + start = System.currentTimeMillis(); + for (int i = 0; i < 1000000; i++) { + linkedList.getFirst(); + } + endTime(start, "linkedList.getFirst "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 1000000; i++) { + garriksList.size(); + } + endTime(start, "garriksList.size "); + + + start = System.currentTimeMillis(); + for (int i = 0; i < 1000000; i++) { + linkedList.size(); + } + endTime(start, "linkedList.size "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 1000000; i++) { + garriksList.isEmpty(); + } + endTime(start, "garriksList.isEmpty "); + + + start = System.currentTimeMillis(); + for (int i = 0; i < 1000000; i++) { + linkedList.isEmpty(); + } + endTime(start, "linkedList.isEmpty "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 100000; i++) { + garriksList.contains(i); + } + endTime(start, "garriksList.contains "); + + + start = System.currentTimeMillis(); + for (int i = 0; i < 100000; i++) { + linkedList.contains(i); + } + endTime(start, "linkedList.contains "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 100000; i++) { + garriksList.get(i); + } + endTime(start, "garriksList.get "); + + + start = System.currentTimeMillis(); + for (int i = 0; i < 100000; i++) { + linkedList.get(i); + } + endTime(start, "linkedList.get "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 100000; i++) { + garriksList.indexOf(i); + } + endTime(start, "garriksList.indexOf "); + + + start = System.currentTimeMillis(); + for (int i = 0; i < 100000; i++) { + linkedList.indexOf(i); + } + endTime(start, "linkedList.indexOf "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 100000; i++) { + garriksList.set(i, i); + } + endTime(start, "garriksList.set "); + + + start = System.currentTimeMillis(); + for (int i = 0; i < 100000; i++) { + linkedList.set(i, i); + } + endTime(start, "linkedList.set "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 10000; i++) { + garriksList.remove(i); + } + endTime(start, "garriksList.remove "); + + + start = System.currentTimeMillis(); + for (int i = 0; i < 10000; i++) { + linkedList.remove(i); + } + endTime(start, "linkedList.remove "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 100000; i++) { + garriksList.clear(); + } + endTime(start, "garriksList.clear "); + + + start = System.currentTimeMillis(); + for (int i = 0; i < 100000; i++) { + linkedList.clear(); + } + endTime(start, "linkedList.clear "); + + start = System.currentTimeMillis(); + for (int i = 0; i < 100000; i++) { + garriksList.add(i, i); + } + endTime(start, "garriksList.add "); + + + start = System.currentTimeMillis(); + for (int i = 0; i < 100000; i++) { + linkedList.add(i, i); + } + endTime(start, "linkedList.add "); + } + +} + From 097cb28e4fdd9082f58af0bb467bb21662b1dc58 Mon Sep 17 00:00:00 2001 From: Frolov Georgy Date: Fri, 10 Dec 2021 19:40:36 +0300 Subject: [PATCH 2/2] mistakes corrected --- src/GarriksCoolerLinkedList.java | 35 ++++++++++++++ src/GarriksHashMap.java | 81 +++++++++++++++++++------------- src/GarriksLinkedList.java | 75 ++++++++++++++--------------- src/GarriksNode.java | 24 +++++----- 4 files changed, 129 insertions(+), 86 deletions(-) create mode 100644 src/GarriksCoolerLinkedList.java diff --git a/src/GarriksCoolerLinkedList.java b/src/GarriksCoolerLinkedList.java new file mode 100644 index 0000000..a774bdc --- /dev/null +++ b/src/GarriksCoolerLinkedList.java @@ -0,0 +1,35 @@ +public class GarriksCoolerLinkedList extends GarriksLinkedList { + + public E getByKey(Object key) { + for (GarriksNode node : this) { + if (node.getKey().equals(key)) { + return node.getItem(); + } + } + return null; + } + + public K getKey(int index) { + return getNode(index).getKey(); + } + + public void addMap(K key, E element) { + for (GarriksNode node : this) { + if (node.getKey().equals(key)) { + node.setKey(key); + return; + } + } + add(element, key); + } + + public boolean add(E o, K key) { + GarriksNode prevNode = tail.getPrev(); + GarriksNode newNode = new GarriksNode<>(o, key, tail, prevNode); + prevNode.setNext(newNode); + tail.setPrev(newNode); + len++; + return true; + } + +} diff --git a/src/GarriksHashMap.java b/src/GarriksHashMap.java index 06d77ff..2aacc65 100644 --- a/src/GarriksHashMap.java +++ b/src/GarriksHashMap.java @@ -1,30 +1,28 @@ +import java.util.ArrayList; import java.util.Collection; +import java.util.List; public class GarriksHashMap implements HashMapInterface { - private GarriksLinkedList[] array; + private final int MINIMAL_LEN_CAUSING_REPLACEMENT = 13; + private final int DEFAULT_CAPACITY = 16; + private final double DEFAULT_LOAD_FACTOR = 0.75; + private GarriksCoolerLinkedList[] array; private int capacity; private double loadFactor; + private int len; public GarriksHashMap() { - this.array = new GarriksLinkedList[16]; - this.capacity = 16; - this.loadFactor = 0.75; + createNewHashMap(); } @Override public int size() { - int size = 0; - for (GarriksLinkedList list : array) { - if (list != null) { - size += list.size(); - } - } - return size; + return len; } @Override public boolean isEmpty() { - return size() == 0; + return len == 0; } @Override @@ -55,10 +53,17 @@ public boolean containsValue(Object value) { return false; } - // хз как делать @Override public Collection values() { - return null; + List result = new ArrayList<>(); + for (GarriksLinkedList bucket : array) { + if (bucket != null) { + for (GarriksNode node : bucket) { + result.add(node.getItem()); + } + } + } + return result; } @Override @@ -67,6 +72,7 @@ public V put(K key, V value) { int bucket = getBucketNum(key); createBucket(bucket); array[bucket].addMap(key, value); + len++; return value; } @@ -85,14 +91,13 @@ public V remove(Object key) { if (array[bucket].size() == 0) { array[bucket] = null; } + len--; return result; } @Override public void clear() { - array = new GarriksLinkedList[16]; - capacity = 16; - loadFactor = 0.75; + createNewHashMap(); } private int getBucketNum(Object key) { @@ -100,28 +105,30 @@ private int getBucketNum(Object key) { } private void checkSize() { - if (size() > loadFactor * capacity) { + if (len > loadFactor * capacity) { capacity *= 2; replacementArray(); } - if (size() > 13 && capacity > size() * loadFactor / 2) { + if (len > MINIMAL_LEN_CAUSING_REPLACEMENT && capacity > len * loadFactor / 2) { capacity /= 2; replacementArray(); } - - } private void replacementArray() { - GarriksLinkedList[] newArray = new GarriksLinkedList[capacity]; - for (GarriksLinkedList bucket : array) { - if (bucket != null) { - for (GarriksNode node : bucket) { - if (newArray[getBucketNum(node.getKey())] == null) { - newArray[getBucketNum(node.getKey())] = new GarriksLinkedList<>(); - } - newArray[getBucketNum(node.getKey())].addMap(node.getKey(), node.getItem()); + GarriksCoolerLinkedList[] newArray = new GarriksCoolerLinkedList[capacity]; + for (GarriksCoolerLinkedList bucket : array) { + if (bucket == null) { + continue; + } + for (GarriksNode node : bucket) { + if (newArray[getBucketNum(node.getKey())] == null) { + newArray[getBucketNum(node.getKey())] = new GarriksCoolerLinkedList<>(); } + int bucketIndex = getBucketNum(node.getKey()); + K currKey = node.getKey(); + V currItem = node.getItem(); + newArray[bucketIndex].addMap(currKey, currItem); } } array = newArray; @@ -129,16 +136,24 @@ private void replacementArray() { private void createBucket(int index) { if (array[index] == null) { - array[index] = new GarriksLinkedList<>(); + array[index] = new GarriksCoolerLinkedList<>(); } } + private void createNewHashMap() { + array = new GarriksCoolerLinkedList[16]; + capacity = DEFAULT_CAPACITY; + loadFactor = DEFAULT_LOAD_FACTOR; + len = 0; + } + @Override public String toString() { - String result = ""; + StringBuilder result = new StringBuilder(); for (GarriksLinkedList bucket : array) { - result = result + bucket + "\n"; + result.append(bucket).append("\n"); } - return result; + return result.toString(); } + } diff --git a/src/GarriksLinkedList.java b/src/GarriksLinkedList.java index 570b814..c5bf276 100644 --- a/src/GarriksLinkedList.java +++ b/src/GarriksLinkedList.java @@ -3,9 +3,9 @@ public class GarriksLinkedList implements LinkedListInterface, Iterable> { - private final GarriksNode head; - private final GarriksNode tail; - private int len; + protected final GarriksNode head; + protected final GarriksNode tail; + protected int len; public GarriksLinkedList() { this.head = new GarriksNode<>(null, null, null); @@ -30,12 +30,17 @@ public boolean isEmpty() { @Override public boolean contains(Object o) { -// Возможно ли каким-либо образом подобное реализовать? -// if (o.getClass() != E) { -// return false; -// } + + if (isEmpty()) { + return false; + } GarriksNode currNode = head.getNext(); + + if (currNode.getItem().getClass() != o.getClass()) { + return false; + } + while (currNode.getItem() != null && !currNode.getItem().equals(o)) { currNode = currNode.getNext(); } @@ -62,36 +67,12 @@ public void add(int index, E element) { len++; } - // метод для добавления узла с ключом - public void addMap(T key, E element) { - for (GarriksNode node : this) { - if (node.getKey().equals(key)) { - node.setItem(element); - node.setKey(key); - return; - } - } - GarriksNode prevNode = tail.getPrev(); - GarriksNode newNode = new GarriksNode<>(element, key, tail, prevNode); - prevNode.setNext(newNode); - tail.setPrev(newNode); - len++; - } @Override public E get(int index) { return getNode(index).getItem(); } - // получение элемента по ключу - public E getByKey(Object key) { - for (GarriksNode node : this) { - if (node.getKey().equals(key)) { - return node.getItem(); - } - } - return null; - } @Override public int indexOf(Object o) { @@ -124,7 +105,10 @@ public E remove(int index) { @Override public boolean remove(Object o) { - GarriksNode currItem = getNode(indexOf(o)); + GarriksNode currItem = getNode(o); + if (currItem.equals(tail) || currItem.equals(head)) { + return false; + } GarriksNode prevItem = currItem.getPrev(); GarriksNode nextItem = currItem.getNext(); prevItem.setNext(nextItem); @@ -135,7 +119,6 @@ public boolean remove(Object o) { @Override public void clear() { - // я же правильно понимаю, что при отсутствии ссылок на объекты (в данном случае ссылок на узлы) эти объекты удаляются из памяти, поэтому можно просто создань новые голову и хвост head.setNext(tail); tail.setPrev(head); len = 0; @@ -145,9 +128,9 @@ public Iterator> iterator() { return new GarriksLinkedListIterator<>(this); } - private GarriksNode getNode(int index) { + protected GarriksNode getNode(int index) { if (index >= len || index < 0) { - throw new IndexOutOfBoundsException(); + throw new IndexOutOfBoundsException(String.format("Attempt to get the index %d, in range 0..%d", index, len)); } GarriksNode currNode = head; for (int i = 0; i < index + 1; i++) { @@ -156,20 +139,30 @@ private GarriksNode getNode(int index) { return currNode; } - public T getKey(int index) { - return getNode(index).getKey(); + protected GarriksNode getNode(Object o) { + GarriksNode currNode = head; + for (int i = 0; i < len; i++) { + if (currNode.getItem().equals(o)) { + return currNode; + } + currNode = currNode.getNext(); + } + return currNode; } + + @Override public String toString() { GarriksNode currElem = head; - String result = "head -> "; + StringBuilder result = new StringBuilder("head <-> "); for (int i = 0; i < len; i++) { currElem = currElem.getNext(); - result = new String(result + currElem.getItem() + " -> "); + result.append(currElem.getItem()).append(" <-> "); } - result = new String(result + "tail"); - return result; + result.append("tail"); + + return result.toString(); } } diff --git a/src/GarriksNode.java b/src/GarriksNode.java index 9969b66..fe12368 100644 --- a/src/GarriksNode.java +++ b/src/GarriksNode.java @@ -1,29 +1,29 @@ import java.util.Iterator; -public class GarriksNode { +public class GarriksNode { private E item; - private T key; - private GarriksNode next; - private GarriksNode prev; + private K key; + private GarriksNode next; + private GarriksNode prev; - public GarriksNode(E item, GarriksNode next, GarriksNode prev) { + public GarriksNode(E item, GarriksNode next, GarriksNode prev) { this.item = item; this.next = next; this.prev = prev; } - public GarriksNode(E item, T key, GarriksNode next, GarriksNode prev) { + public GarriksNode(E item, K key, GarriksNode next, GarriksNode prev) { this.item = item; this.key = key; this.next = next; this.prev = prev; } - public GarriksNode getNext() { + public GarriksNode getNext() { return next; } - public void setNext(GarriksNode newNext) { + public void setNext(GarriksNode newNext) { next = newNext; } @@ -35,19 +35,19 @@ public void setItem(E newItem) { item = newItem; } - public GarriksNode getPrev() { + public GarriksNode getPrev() { return prev; } - public void setPrev(GarriksNode prev) { + public void setPrev(GarriksNode prev) { this.prev = prev; } - public T getKey() { + public K getKey() { return key; } - public void setKey(T key) { + public void setKey(K key) { this.key = key; }