Skip to content

Instantly share code, notes, and snippets.

@YanchevskayaAnna
Created August 13, 2016 09:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save YanchevskayaAnna/b3578dae3a34163fe726c15733b41608 to your computer and use it in GitHub Desktop.
Save YanchevskayaAnna/b3578dae3a34163fe726c15733b41608 to your computer and use it in GitHub Desktop.
package week6.myHashTable;
import java.lang.reflect.Array;
import java.util.*;
/**
* Created by Vladislav on 11.08.2016.
*/
public class MyHashTable<K,V> implements Map, Iterator { //Yanchevskaya A почему Iterator, а не Iterable?
private Node<K,V>[] array;
private int elementsCount;
private float loadFactor;
private int arraySize;
public MyHashTable(float loadFactor, int arraySize) {
array = (Node<K,V>[]) Array.newInstance(Node.class, arraySize);
this.loadFactor = loadFactor;
this.arraySize = arraySize;
}
private int getIndex(Node node){
return node.getKey().hashCode() % arraySize; //Yanchevskaya A лучше брать по модулю, вдруг hashCode отрицательный
}
@Override
public int size() {
return elementsCount;
}
@Override
public boolean isEmpty() {
return elementsCount == 0;
}
@Override
public boolean containsKey(Object key) {
for (int i = 0; i < arraySize; i++) {
Node node = array[i];
if (node != null) {
if (node.getKey().equals(key)) return true;
while (node.getNext() != null) {
node = node.getNext();
if (node.getKey().equals(key)) return true;
}
}
}
return false;
}
@Override
public boolean containsValue(Object value) {
for (int i = 0; i < arraySize; i++) {
Node node = array[i];
if (node != null) {
if (node.getValue().equals(value)) return true;
while (node.getNext() != null) {
node = node.getNext();
if (node.getValue().equals(value)) return true; //Yanchevskaya A node.getValue() может быть null?
}
}
}
return false;
}
@Override
public Object get(Object key) {
for (int i = 0; i < arraySize; i++) {
Node node = array[i];
if (node != null) {
if (node.getKey().equals(key)) return node.getValue();
while (node.getNext() != null) {
node = node.getNext();
if (node.getKey().equals(key)) return node.getValue();
}
}
}
return null;
}
@Override
public Object put(Object key, Object value) {
Node node = new Node(key, value);
if (elementsCount/arraySize >= loadFactor) rehashing();
int index = key.hashCode() % arraySize;
if (array[index] == null) {
array[index] = node;
} else {
Node subNode = array[index].getNext();
if (subNode != null) { //Yanchevskaya A И if и while - надо что-то одно, нагромождение. Есть еще цикл do while
while (subNode != null) {
if (subNode.getNext() != null) {
subNode = subNode.getNext();
} else break;
}
subNode.setNext(node);
} else {
array[index].setNext(node);
}
}
elementsCount++;
return value; //Yanchevskaya A @return the previous value associated with <tt>key</tt>, or
}
private void rehashing(){
arraySize *= 2;
Node<K,V>[] temp = (Node<K,V>[]) Array.newInstance(Node.class, arraySize);
Node nodeTmp;
for (int i = 0; i < array.length; i++) {
Node node = array[i];
if (node != null){ //Yanchevskaya A чтобы меньше вложений: if (node == null) continue;
if (node.getNext() != null){
while(node != null){
int index = getIndex(node);
nodeTmp = node.getNext();
node.setNext(null);
if (temp[index] == null){
temp[index] = node;
} else {
temp[index].setNext(node);//Yanchevskaya A а если там цепочка уже?
}
node.setNext(nodeTmp);
node = node.getNext(); //Yanchevskaya Можно упростить: текщую ноду вооюще не менять, а при рехешировании создавать новую ноду на основании ключа и значения текущей
}
} else {
int index = getIndex(node);
if (temp[index] == null){
temp[index] = node;
} else {
temp[index].setNext(node); //Yanchevskaya A а если там цепочка уже?
}
}
}
}
array = temp;
}
@Override
public Object remove(Object key) {
Object value = null;
Node node;
for (int i = 0; i < arraySize; i++) {
node = array[i];
if (node != null) {
if (node.getNext() == null){
if (node.getKey().equals(key)) {
value = (V) node.getValue();
array[i] = null;
break;
}
} else {
if (node.getKey().equals(key)){
value = (V) node.getValue();
array[i] = node.getNext();
break;
} else {
node = node.getNext();
while (node != null) {
if (node.getKey().equals(key)) {
value = (V) node.getValue();
array[i] = node.getNext(); //Yanchevskaya A У элемента, который перед удаляемым нужно также изменить next, иначе цепочка разрывается
break;
}
node = node.getNext();
}
}
}
}
}
elementsCount--;
return value;
}
@Override
public void putAll(Map m) {
MyHashTable map = (MyHashTable<K,V>)m;
Node[] arrayIn = map.getArray();
Node node;
Node tmp;
for (int i = 0; i < arrayIn.length; i++) {
node = arrayIn[i];
if (node != null){ //Yanchevskaya A почему нельзя просто while(node != null){put(node.getKey(), node.getValue()); node = node.getNext();}
if (node.getNext() != null){
while(node != null){
tmp = node.getNext();
node.setNext(null);
put(node.getKey(), node.getValue());
node.setNext(tmp);
node = node.getNext();
}
} else {
put(node.getKey(), node.getValue());
}
}
}
}
@Override
public void clear() {
array = null; //Yanchevskaya A и elementsCount = 0;
}
@Override
public Set keySet() {
Set<K> set = new HashSet<>(elementsCount, loadFactor);
Node<K,V> node;
for (int i = 0; i < arraySize; i++) {
node = array[i];
if (node != null) {
while(node != null) {
set.add(node.getKey());
node = node.getNext();
}
}
}
return set;
}
@Override
public Collection values() {
Set<V> set = new HashSet<>(elementsCount, loadFactor);
Node<K,V> node;
for (int i = 0; i < arraySize; i++) {
node = array[i];
if (node != null) {//Yanchevskaya A и if и while, надо упрощать
while(node != null) {
set.add(node.getValue());
node = node.getNext();
}
}
}
return set;
}
@Override
public Set<Entry> entrySet() {
Set<Map.Entry> set = new HashSet<>(elementsCount, loadFactor);
Node<K,V> node;
for (int i = 0; i < arraySize; i++) {
node = array[i];
if (node != null) {
while(node != null) {
set.add(node);
node = node.getNext();
}
}
}
return set;
}
@Override
public boolean hasNext() {
//will be implemented till Saturday
return false;
}
@Override
public Object next() {
//will be implemented till Saturday
return null;
}
@Override
public void remove() {
//will be implemented till Saturday
}
public Node<K, V>[] getArray() {
return array;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment