Custom LinkedHashMap Implementation

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
0
down vote

favorite












I implemented my own LinkedHashMap in java.



 public class LinkedHashMap<K,V> 
private Entry<K,V> buckets;
private int capacity=4;
private Entry<K,V> head;
private Entry<K,V>tail;
static class Entry<K,V>

K key;
V value;
Entry<K,V>next;
Entry<K,V>before;
Entry<K,V>after;
public Entry(K key ,V value,Entry<K,V> next)

this.key=key;
this.value=value;
this.next=next;


public LinkedHashMap()

buckets=new Entry[capacity];

public void put(K key,V value)

if(key==null)//not allow null key

return;

boolean replace=false;
int hash=hash(key);
Entry<K,V> newEntry = new Entry<K,V>(key, value, null);
//insert in bucket
// maintainOrderAfterInsert(newEntry);
Entry<K,V>curr=buckets[hash];

if(curr==null)

buckets[hash]=newEntry;

else

Entry<K,V> prev=null;
while(curr!=null)

if(curr.key.equals(key))

replace=true;
curr.value=value;
break;

prev=curr;
curr=curr.next;

if(prev!=null)
prev.next=newEntry;

//newEntry.next=curr;
//buckets[hash]=newEntry;
if(replace==false)
insertInList(newEntry);
//buckets[hash]=newEntry;

private void insertInList(Entry<K,V> newEntry)

if(head==null)

head=newEntry;
tail=newEntry;

else

tail.after=newEntry;
newEntry.before=tail;
tail=newEntry;


public V get(K key)

int hash=hash(key);
Entry<K,V> curr=buckets[hash];
while(curr!=null)

if(curr.key.equals(key))

return curr.value;

curr=curr.next;

return null;


public void print()

Entry<K,V>curr=head;
while(curr!=null)

System.out.println("key is "+ curr.key+"val is "+ curr.value+"->");
curr=curr.after;


private int hash(K key)
return Math.abs(key.hashCode()) % capacity;


public void remove(K key)

int hash=hash(key);
Entry<K,V>curr=buckets[hash];
if(curr==null)//no exist

return;

Entry<K,V>p=null;
Entry<K,V>n;
while(curr!=null)

n=curr.next;
if(curr.key.equals(key))

if(p==null)//first

buckets[hash]=buckets[hash].next;

else

p.next=n;

//adjust Linked List
adjustList(curr);
break;

p=curr;
curr=n;



private void adjustList(Entry<K,V> curr)

if(curr==head)

head=head.after;
if(head==null)

tail=null;


else if (curr==tail)

tail=tail.before;
tail.after=null;

else

curr.before.after=curr.after;
curr.after.before=curr.before;


public void deleteAll()

head=null;
tail=null;
for(int i=0;i<capacity;i++)

buckets[i]=null;





Null key is not allowed. If the same key appears,value is updated. In every bucket,new element added at the end. I want to review how optimal are the functions ,especially deleteAll().



In a language like C++, I have to explicitly free memory .



In JAVA,just setting references to null will work?



Any suggestions on any other function ??







share|improve this question





















  • shouldn't deleteAll be named more aptly clear? deleteAll implies you give it a collection of elements, all of which you want to delete from this map.
    – Mark Jeronimus
    Jun 7 at 8:36

















up vote
0
down vote

favorite












I implemented my own LinkedHashMap in java.



 public class LinkedHashMap<K,V> 
private Entry<K,V> buckets;
private int capacity=4;
private Entry<K,V> head;
private Entry<K,V>tail;
static class Entry<K,V>

K key;
V value;
Entry<K,V>next;
Entry<K,V>before;
Entry<K,V>after;
public Entry(K key ,V value,Entry<K,V> next)

this.key=key;
this.value=value;
this.next=next;


public LinkedHashMap()

buckets=new Entry[capacity];

public void put(K key,V value)

if(key==null)//not allow null key

return;

boolean replace=false;
int hash=hash(key);
Entry<K,V> newEntry = new Entry<K,V>(key, value, null);
//insert in bucket
// maintainOrderAfterInsert(newEntry);
Entry<K,V>curr=buckets[hash];

if(curr==null)

buckets[hash]=newEntry;

else

Entry<K,V> prev=null;
while(curr!=null)

if(curr.key.equals(key))

replace=true;
curr.value=value;
break;

prev=curr;
curr=curr.next;

if(prev!=null)
prev.next=newEntry;

//newEntry.next=curr;
//buckets[hash]=newEntry;
if(replace==false)
insertInList(newEntry);
//buckets[hash]=newEntry;

private void insertInList(Entry<K,V> newEntry)

if(head==null)

head=newEntry;
tail=newEntry;

else

tail.after=newEntry;
newEntry.before=tail;
tail=newEntry;


public V get(K key)

int hash=hash(key);
Entry<K,V> curr=buckets[hash];
while(curr!=null)

if(curr.key.equals(key))

return curr.value;

curr=curr.next;

return null;


public void print()

Entry<K,V>curr=head;
while(curr!=null)

System.out.println("key is "+ curr.key+"val is "+ curr.value+"->");
curr=curr.after;


private int hash(K key)
return Math.abs(key.hashCode()) % capacity;


public void remove(K key)

int hash=hash(key);
Entry<K,V>curr=buckets[hash];
if(curr==null)//no exist

return;

Entry<K,V>p=null;
Entry<K,V>n;
while(curr!=null)

n=curr.next;
if(curr.key.equals(key))

if(p==null)//first

buckets[hash]=buckets[hash].next;

else

p.next=n;

//adjust Linked List
adjustList(curr);
break;

p=curr;
curr=n;



private void adjustList(Entry<K,V> curr)

if(curr==head)

head=head.after;
if(head==null)

tail=null;


else if (curr==tail)

tail=tail.before;
tail.after=null;

else

curr.before.after=curr.after;
curr.after.before=curr.before;


public void deleteAll()

head=null;
tail=null;
for(int i=0;i<capacity;i++)

buckets[i]=null;





Null key is not allowed. If the same key appears,value is updated. In every bucket,new element added at the end. I want to review how optimal are the functions ,especially deleteAll().



In a language like C++, I have to explicitly free memory .



In JAVA,just setting references to null will work?



Any suggestions on any other function ??







share|improve this question





















  • shouldn't deleteAll be named more aptly clear? deleteAll implies you give it a collection of elements, all of which you want to delete from this map.
    – Mark Jeronimus
    Jun 7 at 8:36













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I implemented my own LinkedHashMap in java.



 public class LinkedHashMap<K,V> 
private Entry<K,V> buckets;
private int capacity=4;
private Entry<K,V> head;
private Entry<K,V>tail;
static class Entry<K,V>

K key;
V value;
Entry<K,V>next;
Entry<K,V>before;
Entry<K,V>after;
public Entry(K key ,V value,Entry<K,V> next)

this.key=key;
this.value=value;
this.next=next;


public LinkedHashMap()

buckets=new Entry[capacity];

public void put(K key,V value)

if(key==null)//not allow null key

return;

boolean replace=false;
int hash=hash(key);
Entry<K,V> newEntry = new Entry<K,V>(key, value, null);
//insert in bucket
// maintainOrderAfterInsert(newEntry);
Entry<K,V>curr=buckets[hash];

if(curr==null)

buckets[hash]=newEntry;

else

Entry<K,V> prev=null;
while(curr!=null)

if(curr.key.equals(key))

replace=true;
curr.value=value;
break;

prev=curr;
curr=curr.next;

if(prev!=null)
prev.next=newEntry;

//newEntry.next=curr;
//buckets[hash]=newEntry;
if(replace==false)
insertInList(newEntry);
//buckets[hash]=newEntry;

private void insertInList(Entry<K,V> newEntry)

if(head==null)

head=newEntry;
tail=newEntry;

else

tail.after=newEntry;
newEntry.before=tail;
tail=newEntry;


public V get(K key)

int hash=hash(key);
Entry<K,V> curr=buckets[hash];
while(curr!=null)

if(curr.key.equals(key))

return curr.value;

curr=curr.next;

return null;


public void print()

Entry<K,V>curr=head;
while(curr!=null)

System.out.println("key is "+ curr.key+"val is "+ curr.value+"->");
curr=curr.after;


private int hash(K key)
return Math.abs(key.hashCode()) % capacity;


public void remove(K key)

int hash=hash(key);
Entry<K,V>curr=buckets[hash];
if(curr==null)//no exist

return;

Entry<K,V>p=null;
Entry<K,V>n;
while(curr!=null)

n=curr.next;
if(curr.key.equals(key))

if(p==null)//first

buckets[hash]=buckets[hash].next;

else

p.next=n;

//adjust Linked List
adjustList(curr);
break;

p=curr;
curr=n;



private void adjustList(Entry<K,V> curr)

if(curr==head)

head=head.after;
if(head==null)

tail=null;


else if (curr==tail)

tail=tail.before;
tail.after=null;

else

curr.before.after=curr.after;
curr.after.before=curr.before;


public void deleteAll()

head=null;
tail=null;
for(int i=0;i<capacity;i++)

buckets[i]=null;





Null key is not allowed. If the same key appears,value is updated. In every bucket,new element added at the end. I want to review how optimal are the functions ,especially deleteAll().



In a language like C++, I have to explicitly free memory .



In JAVA,just setting references to null will work?



Any suggestions on any other function ??







share|improve this question













I implemented my own LinkedHashMap in java.



 public class LinkedHashMap<K,V> 
private Entry<K,V> buckets;
private int capacity=4;
private Entry<K,V> head;
private Entry<K,V>tail;
static class Entry<K,V>

K key;
V value;
Entry<K,V>next;
Entry<K,V>before;
Entry<K,V>after;
public Entry(K key ,V value,Entry<K,V> next)

this.key=key;
this.value=value;
this.next=next;


public LinkedHashMap()

buckets=new Entry[capacity];

public void put(K key,V value)

if(key==null)//not allow null key

return;

boolean replace=false;
int hash=hash(key);
Entry<K,V> newEntry = new Entry<K,V>(key, value, null);
//insert in bucket
// maintainOrderAfterInsert(newEntry);
Entry<K,V>curr=buckets[hash];

if(curr==null)

buckets[hash]=newEntry;

else

Entry<K,V> prev=null;
while(curr!=null)

if(curr.key.equals(key))

replace=true;
curr.value=value;
break;

prev=curr;
curr=curr.next;

if(prev!=null)
prev.next=newEntry;

//newEntry.next=curr;
//buckets[hash]=newEntry;
if(replace==false)
insertInList(newEntry);
//buckets[hash]=newEntry;

private void insertInList(Entry<K,V> newEntry)

if(head==null)

head=newEntry;
tail=newEntry;

else

tail.after=newEntry;
newEntry.before=tail;
tail=newEntry;


public V get(K key)

int hash=hash(key);
Entry<K,V> curr=buckets[hash];
while(curr!=null)

if(curr.key.equals(key))

return curr.value;

curr=curr.next;

return null;


public void print()

Entry<K,V>curr=head;
while(curr!=null)

System.out.println("key is "+ curr.key+"val is "+ curr.value+"->");
curr=curr.after;


private int hash(K key)
return Math.abs(key.hashCode()) % capacity;


public void remove(K key)

int hash=hash(key);
Entry<K,V>curr=buckets[hash];
if(curr==null)//no exist

return;

Entry<K,V>p=null;
Entry<K,V>n;
while(curr!=null)

n=curr.next;
if(curr.key.equals(key))

if(p==null)//first

buckets[hash]=buckets[hash].next;

else

p.next=n;

//adjust Linked List
adjustList(curr);
break;

p=curr;
curr=n;



private void adjustList(Entry<K,V> curr)

if(curr==head)

head=head.after;
if(head==null)

tail=null;


else if (curr==tail)

tail=tail.before;
tail.after=null;

else

curr.before.after=curr.after;
curr.after.before=curr.before;


public void deleteAll()

head=null;
tail=null;
for(int i=0;i<capacity;i++)

buckets[i]=null;





Null key is not allowed. If the same key appears,value is updated. In every bucket,new element added at the end. I want to review how optimal are the functions ,especially deleteAll().



In a language like C++, I have to explicitly free memory .



In JAVA,just setting references to null will work?



Any suggestions on any other function ??









share|improve this question












share|improve this question




share|improve this question








edited Jun 3 at 13:21









πάντα ῥεῖ

3,82431126




3,82431126









asked Jun 3 at 13:18









somerandomguy

31




31











  • shouldn't deleteAll be named more aptly clear? deleteAll implies you give it a collection of elements, all of which you want to delete from this map.
    – Mark Jeronimus
    Jun 7 at 8:36

















  • shouldn't deleteAll be named more aptly clear? deleteAll implies you give it a collection of elements, all of which you want to delete from this map.
    – Mark Jeronimus
    Jun 7 at 8:36
















shouldn't deleteAll be named more aptly clear? deleteAll implies you give it a collection of elements, all of which you want to delete from this map.
– Mark Jeronimus
Jun 7 at 8:36





shouldn't deleteAll be named more aptly clear? deleteAll implies you give it a collection of elements, all of which you want to delete from this map.
– Mark Jeronimus
Jun 7 at 8:36











1 Answer
1






active

oldest

votes

















up vote
0
down vote



accepted










  1. yes, setting a variable to null will make it eligible for garbage collection (which is invoked implicitly by the run time platform) this is also true when a variable becomes out of scope (for example all local variables become eligible for garbage collection when the method exits).


  2. in put() you do not allow null key, but you do not alert the client in any way. You should consider raising an exception and then the client may choose to regard or disregard it. you can make a custom checked exception (to force clients to catch it) or use the predefined unchecked IllegalArgumentException.


  3. regrding print(): this is considered bad practice becasue it predetermines the destination of the print operation. clients may want to print to stderr or to a file or to an HTTP response etc. it is better to implement toString() and let the client decide where it goes.


  4. regrding remove(): you should consider returning the deleted value. This serves two purposes: it indicates if key was found and it supports stack's pop() (or queue's pull()) that does "get and remove".


  5. there are several additional functionalities you can add like test if key exists, put only if key is absent, iterate on keys, on values. why don't you take a look at Map interface. and perhaps consider implementing it?






share|improve this answer





















    Your Answer




    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195745%2fcustom-linkedhashmap-implementation%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote



    accepted










    1. yes, setting a variable to null will make it eligible for garbage collection (which is invoked implicitly by the run time platform) this is also true when a variable becomes out of scope (for example all local variables become eligible for garbage collection when the method exits).


    2. in put() you do not allow null key, but you do not alert the client in any way. You should consider raising an exception and then the client may choose to regard or disregard it. you can make a custom checked exception (to force clients to catch it) or use the predefined unchecked IllegalArgumentException.


    3. regrding print(): this is considered bad practice becasue it predetermines the destination of the print operation. clients may want to print to stderr or to a file or to an HTTP response etc. it is better to implement toString() and let the client decide where it goes.


    4. regrding remove(): you should consider returning the deleted value. This serves two purposes: it indicates if key was found and it supports stack's pop() (or queue's pull()) that does "get and remove".


    5. there are several additional functionalities you can add like test if key exists, put only if key is absent, iterate on keys, on values. why don't you take a look at Map interface. and perhaps consider implementing it?






    share|improve this answer

























      up vote
      0
      down vote



      accepted










      1. yes, setting a variable to null will make it eligible for garbage collection (which is invoked implicitly by the run time platform) this is also true when a variable becomes out of scope (for example all local variables become eligible for garbage collection when the method exits).


      2. in put() you do not allow null key, but you do not alert the client in any way. You should consider raising an exception and then the client may choose to regard or disregard it. you can make a custom checked exception (to force clients to catch it) or use the predefined unchecked IllegalArgumentException.


      3. regrding print(): this is considered bad practice becasue it predetermines the destination of the print operation. clients may want to print to stderr or to a file or to an HTTP response etc. it is better to implement toString() and let the client decide where it goes.


      4. regrding remove(): you should consider returning the deleted value. This serves two purposes: it indicates if key was found and it supports stack's pop() (or queue's pull()) that does "get and remove".


      5. there are several additional functionalities you can add like test if key exists, put only if key is absent, iterate on keys, on values. why don't you take a look at Map interface. and perhaps consider implementing it?






      share|improve this answer























        up vote
        0
        down vote



        accepted







        up vote
        0
        down vote



        accepted






        1. yes, setting a variable to null will make it eligible for garbage collection (which is invoked implicitly by the run time platform) this is also true when a variable becomes out of scope (for example all local variables become eligible for garbage collection when the method exits).


        2. in put() you do not allow null key, but you do not alert the client in any way. You should consider raising an exception and then the client may choose to regard or disregard it. you can make a custom checked exception (to force clients to catch it) or use the predefined unchecked IllegalArgumentException.


        3. regrding print(): this is considered bad practice becasue it predetermines the destination of the print operation. clients may want to print to stderr or to a file or to an HTTP response etc. it is better to implement toString() and let the client decide where it goes.


        4. regrding remove(): you should consider returning the deleted value. This serves two purposes: it indicates if key was found and it supports stack's pop() (or queue's pull()) that does "get and remove".


        5. there are several additional functionalities you can add like test if key exists, put only if key is absent, iterate on keys, on values. why don't you take a look at Map interface. and perhaps consider implementing it?






        share|improve this answer













        1. yes, setting a variable to null will make it eligible for garbage collection (which is invoked implicitly by the run time platform) this is also true when a variable becomes out of scope (for example all local variables become eligible for garbage collection when the method exits).


        2. in put() you do not allow null key, but you do not alert the client in any way. You should consider raising an exception and then the client may choose to regard or disregard it. you can make a custom checked exception (to force clients to catch it) or use the predefined unchecked IllegalArgumentException.


        3. regrding print(): this is considered bad practice becasue it predetermines the destination of the print operation. clients may want to print to stderr or to a file or to an HTTP response etc. it is better to implement toString() and let the client decide where it goes.


        4. regrding remove(): you should consider returning the deleted value. This serves two purposes: it indicates if key was found and it supports stack's pop() (or queue's pull()) that does "get and remove".


        5. there are several additional functionalities you can add like test if key exists, put only if key is absent, iterate on keys, on values. why don't you take a look at Map interface. and perhaps consider implementing it?







        share|improve this answer













        share|improve this answer



        share|improve this answer











        answered Jun 4 at 8:02









        Sharon Ben Asher

        2,038512




        2,038512






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195745%2fcustom-linkedhashmap-implementation%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Greedy Best First Search implementation in Rust

            Function to Return a JSON Like Objects Using VBA Collections and Arrays

            C++11 CLH Lock Implementation