= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

Interested in artificial intelligence partners, share a my friend’s artificial intelligence tutorial. Zero basis! Easy to understand! Funny humor! You can see if it helps you, click here to see the tutorial.

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

Be a positive person

Code, fix bugs, improve yourself

I have a paradise, facing programming, spring flowers!

Seems to be a simple problem, in fact, it contains a lot of things!

Requirements:

When you implement a key that is stored (of any type) in a HashMap, the values in the key are not overwritten, but can be superimposed!

When we get a requirement, we should first analyze to see whether the requirement can be realized, based on existing knowledge (experience), and then see how the requirement can be realized through some of the current technologies.

To insert the same key into a HashMap without overwriting it, you must understand some of the mechanics of a HashMap. First look at the put method of a HashMap:

See from the JDK API how the PUT of a HashMap previously stored a key and replaced the old value with a new value when specifying the same key.

Here is an example of code:

public static void main(String[] args) {
    Map<String, Object> map = new HashMap<>();

    map.put("aflyun"."Java Programming Technology Paradise");

    map.put("aflyun"."Yan 'an people living in Changsha."); System.out.println(map.toString()); } -- print: -- {aflyun= Yan 'an people living in Changsha}Copy the code

Using the above example, why is the old value replaced by the new value when the same key is stored?

To see why, look no further than the source implementation of HashMap. Put (K key, V value);

/** * Put method of HashMap **/
public V put(K key, V value) {
    return putVal(hash(key), key, value, false.true);
}
/** * containsKey method of HashMap **/
public boolean containsKey(Object key) {
    returngetNode(hash(key), key) ! =null;
}

/** * hash the stored key with key.hashcode ()! * * /
static final int hash(Object key) {
    int h;
    return (key == null)?0 : (h = key.hashCode()) ^ (h >>> 16);
}
Copy the code

To check whether the PUT and key are the same key, use the following logic:

if(e.hash == hash && ((k = e.key) == key || (key ! =null && key.equals(k))))
Copy the code

Determine whether the Hash is consistent, and then determine whether the incoming key and the current set have the same key. If the keys are the same, the new value replaces the old one. Which is used in the judgment

  • = =
  • equals

== equals equals equals equals equals equals Equals Equals Equals equals equals equals equals equals equals equals equals equals equals equals equals Equals Equals Equals Equals Equals


== equals = equals

1) For ==, if applied to variables of basic data type, directly compare whether the stored “value” is equal; If applied to a variable of a reference type, it compares the address of the object to which it points!

2) For equals, note that equals does not apply to variables of primitive data types. If the equals method is not overridden, it compares the addresses of the objects to which the variables referring to the type refer; A class such as String overrides equals to compare the contents of the objects to which it refers.


With the above analysis foundation, it is relatively simple to implement for the above String key. Because String already implements HashCode and equals as follows:

  • Custom HashMap
public class MyHashMap<K> extends HashMap<K.String> {

    /** * Use containsKey in the HashMap to check if the key already exists *@param key
     * @param value
     * @return* /
    @Override
    public String put(K key, String value) {
        String newV = value;
        if (containsKey(key)) {
            String oldV = get(key);
            newV = oldV + "-" + newV;
        }
        return super.put(key, newV); }}Copy the code
  • The put operation is performed on the key of String type
public static void main(String[] args) {
    MyHashMap<String> map = new MyHashMap<String>();

    map.put("aflyun"."Java Programming Technology Paradise");

    map.put("aflyun"."Yan 'an people living in Changsha.");

    map.put("aflyun"."I look forward to having you in the park."); System.out.println(map.toString()); } -- print: -- {aflyun=Java programming technology paradise -- Yan 'an people living in Changsha -- looking forward to your joining paradise}Copy the code

At this point, the same key content is superimposed, not replaced! So how can it be a custom class that’s going to be a key? How do you do that?

So you just overwrite hashCode and equals.

public class PrettyGirl {
    /** * Girl unique authentication ID */
    private String id;
    /** ** who is the name of the girl */
    private String name;


    @Override
    public boolean equals(Object o) {
        if (this == o) {return true; }if (o == null|| getClass() ! = o.getClass()) {return false; } PrettyGirl that = (PrettyGirl) o;return Objects.equals(id, that.id) &&
                Objects.equals(name, that.name);
    }

    @Override
    public int hashCode(a) {
        returnObjects.hash(id, name); }}Copy the code
  • User-defined types are used as keys to perform the PUT operation
public static void main(String[] args) {

    PrettyGirl prettyGirl = new PrettyGirl();

    Map<PrettyGirl,String> map = new HashMap<>();

    map.put(prettyGirl, "Java Programming Technology Paradise");

    map.put(prettyGirl, "Yan 'an people living in Changsha.");

    map.put(prettyGirl, "I look forward to joining you in the park.");

    System.out.println("map :" + map.toString());

    MyHashMap<PrettyGirl> myMap = new MyHashMap<PrettyGirl>();

    myMap.put(prettyGirl, "Java Programming Technology Paradise");

    myMap.put(prettyGirl, "Yan 'an people living in Changsha.");

    myMap.put(prettyGirl, "I look forward to joining you in the park.");

    System.out.println("myMap :"+ myMap.toString()); } -- Print: -- map :{com.happy.prettygirl@3C1 = Looking forward to joining the park with you} myMap :{com.happy.prettygirl@3C1 =Java Programming Technology Paradise -- Yan 'an people living in Changsha -- looking forward to joining the paradise with you!Copy the code

Summary: Implement the initial requirements

If it’s something like String, you’ve overridden hashCode and equals. All you need to do is create your own HashMap class and override PUT.

2. If it is a custom class, you must override hashCode and equals and then use the custom HashMap class.

Specific code judgment logic:

To determine the existence of a key, compare the hashCode of the key first, and then compare the hashCode() and equals() methods to add duplicate elements. If you want to stack values, use containsKey() before calling put() to check if there are any duplicate keys. If so, use get() to get the old value plus the new value.

Relevant knowledge involved in this paper:

1, HashMap related source code

==, equals, and hashCode

3. Hash algorithm

Related interview questions:

1. Why do I have to override hashCode to override equals?

2. When do memory leaks occur using HashMap?


Thank you for reading, if you think this blog is helpful to you, please like or like, let more people see! I wish you happy every day!



No matter what you do, as long as you stick to it, you will see the difference! On the road, neither humble nor pushy!

I wish you and I can become the best of themselves on the way of life, to become an independent person

© Alfayun who is getting better every day