Giter VIP home page Giter VIP logo

Comments (7)

emirpasic avatar emirpasic commented on July 22, 2024

@danielzhangy that behaviour is by design, I just have to write that in the documentation.

Not sure why java does it this way, but I used their ideology: https://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashMap.html

... . Note that insertion order is not affected if a key is re-inserted into the map. (A key k is reinserted into a map m if m.put(k, v) is invoked when m.containsKey(k) would return true immediately prior to the invocation.). ...

I followed their documentation as not to be "smart" about it, but it can be implemented either way.

from gods.

danielchang-Z avatar danielchang-Z commented on July 22, 2024

@emirpasic I think the reason that java does it this way is that java wants the iterative sequence of LinkedHashMap to be close to the k-v entry input order, it is more ergonomic.

from gods.

emirpasic avatar emirpasic commented on July 22, 2024

@danielzhangy yes, I suppose it all depends at how we define "insertion".

Does placing the same element into set or map constitute insertion? According to Java, they don't treat it as a new insertion. I am really not sure about this one, might get philosophical :D

I will leave this question open in case somebody else has an opinion on this, for now I leave it with the Java's idea of what "insertion" really means.

from gods.

danielchang-Z avatar danielchang-Z commented on July 22, 2024

@emirpasic yes, it depends on the definition of "insertion".

Thanks to your reminder, I read the source code of Java 11. Java treats the same element placing in two different ways, it depends on the initial condition named accessOrder. If accessOrder is false, Java treats the same element placing as updating, otherwise, Java treats it as a special new insertion(updating the value of mapping key and moving the element to the tail of order list).

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            Node<K,V> e; K k;
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;
            else if (p instanceof TreeNode)
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            else {
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = newNode(hash, key, value, null);
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
    }


void afterNodeAccess(Node<K,V> e) { // move node to last
        LinkedHashMap.Entry<K,V> last;
        if (accessOrder && (last = tail) != e) {
            LinkedHashMap.Entry<K,V> p =
                (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
            p.after = null;
            if (b == null)
                head = a;
            else
                b.after = a;
            if (a != null)
                a.before = b;
            else
                last = b;
            if (last == null)
                head = p;
            else {
                p.before = last;
                last.after = p;
            }
            tail = p;
            ++modCount;
        }
    }

from gods.

emirpasic avatar emirpasic commented on July 22, 2024

@danielzhangy thanks for the research, it gave me an idea that it's best to have both. I think I'll add that option also to the LinkedHashSet and LinkedHashMap to configure this behavior or specialized functions that behave in one or the other way. Hwever, oI am still not sure what the default behavior should be, should the same element be evicted upon reinsertion and added to the end or should the default behavior follow Java's default behavior, i.e. no change in insertion order.

from gods.

danielchang-Z avatar danielchang-Z commented on July 22, 2024

@emirpasic I prefer to choose current implementation as default behavior, and make another way as optional, by considering the performance of operation. So what do you think?

from gods.

emirpasic avatar emirpasic commented on July 22, 2024

@danielzhangy i agree with you and i'll leave the current implementation as default, but will provide a way to modify this behavior.

from gods.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.