JAVA HashSet Remove Duplicate value principle __java

Source: Internet
Author: User
A set in Java is a collection that does not contain duplicate elements, specifically an element pair that does not contain e1.equals (E2). Allows NULL to be added in set. Set does not guarantee the order of elements in the collection.

When an element is added to a set, if the specified element does not exist, the addition succeeds. That is, if the element E1 (E==null e1==null:e.queals (E1)) is not present in the set, E1 can be added to the set.


The following is an example of a implementation class hashset of Set, which briefly introduces the principle of set repeat implementation:

Package com.darren.test.overide;

public class CustomString {
    private String value;

    Public customstring () {This
        ("");
    }

    Public customstring (String value) {
        this.value = value;
    }
}

Package com.darren.test.overide;

Import Java.util.HashSet;
Import Java.util.Set;

public class Hashsettest {public
    static void Main (string[] args) {
        string a = new string ("a");
        String b = new String ("A");
        
        CustomString C = new CustomString ("B");
        CustomString d = new CustomString ("B");
        
        System.out.println ("a.equals (b) = =" + a.equals (b));
        System.out.println ("c.equals (d) = =" + c.equals (d));
        
        set<object> set = new Hashset<object> ();
        Set.add (a);
        Set.add (b);
        Set.add (c);
        Set.add (d);
        
        System.out.println ("set.size () = =" + set.size ());
        
        For (object Object:set) {System.out.println (object);}}}

The results of the operation are as follows:

A.equals (b) = = True
c.equals (d) = = False
set.size () = = 3
com.darren.test.overide.customstring@2c39d2
A
Com.darren.test.overide.customstring@5795ce


Perhaps you have seen the key, yes, is the Equals method. It is not appropriate to say that it should be the Equals and Hashcode method. Why do you say that, let's change the CustomString class in the test:

Package com.darren.test.overide;

public class CustomString {
    private String value;

    Public customstring () {This
        ("");
    }

    Public customstring (String value) {
        this.value = value;
    }

    @Override public
    boolean equals (Object obj) {
        if (this = = obj) {return
            
            true;
        } else if (obj Instanceo F customstring) {
            customstring customstring = (customstring) obj;
            
            return customString.value.equals (value);
        } else {return
            
            false;}}}

Test results:

A.equals (b) = = True
c.equals (d) = = True
set.size () = 3
com.darren.test.overide.customstring@12504e0
A
Com.darren.test.overide.customstring@1630eb6

This time the Equals return value is true, but the set size is still 3

Let's keep changing.

Package com.darren.test.overide;

public class CustomString {
    private String value;

    Public customstring () {This
        ("");
    }

    Public customstring (String value) {
        this.value = value;
    }

    @Override public
    int hashcode () {
        //return Super.hashcode ();
        return 1;
    }
}

Then look at the results:

A.equals (b) = = True
c.equals (d) = = False
set.size () = = 3
com.darren.test.overide.customstring@1
com.darren.test.overide.customstring@1
A


Overriding the Hashcode method only, not overriding the Equals method

and finally change it.

Package com.darren.test.overide;

public class CustomString {
    private String value;

    Public customstring () {This
        ("");
    }

    Public customstring (String value) {
        this.value = value;
    }

    @Override public
    boolean equals (Object obj) {
        if (this = = obj) {return

            true;
        } else if (obj instanceof customstring) {
            customstring customstring = (customstring) obj;

            return customString.value.equals (value);
        } else {return

            false;
        }
    }

    @Override public
    int hashcode () {
        //return Super.hashcode ();
        return 1;
    }
}

Final results:

A.equals (b) = = True
c.equals (d) = = True
set.size () = = 2
com.darren.test.overide.customstring@1
A


OK, prove that you need to rewrite the Equals method and the Hashcode method to see the principle:

Java.lnag.Object of the hashcode in the contract:

1. During an application execution, if the information used to compare the Equals method of an object is not modified, the Hashcode method is called multiple times on the object, and it must consistently return the same integer.

2. If two objects are equal according to the Equals (object O) method, the Hashcode method that calls either of the two objects must produce the same integer result.

3. If two objects are not equal according to the Equals (object O) method, the Hashcode method of either of these two objects is called, and no different integer results are required. However, if they can be different, they may improve the performance of the hash table.


In HashSet, the basic operations are implemented at the HashMap level, because the hashset is stored in hashmap with the underlying data. When an element is added to the HashSet, the hashcode value of the element is computed first, and then the storage location of the element is computed using the (hashcode)% of the element (the size of the HashMap set) +1, if the position is empty, the element is added; The Equals method is used to compare whether the elements are equal, equality is not added, or an empty space is added.

The following is part of the source code of HashSet:

Package java.util; 
    public class Hashset<e> extends abstractset<e> implements Set<e>, Cloneable, java.io.Serializable {   

    Static final Long serialversionuid = -5024744406713321676l;   
    The bottom layer uses HASHMAP to hold all the elements in the hashset.   
   
    private transient hashmap<e,object> map;   
    Defines a virtual object as the value of HashMap, which defines this object as static final.   

    private static final Object PRESENT = new Object (); 
     /** * The default parameterless constructor constructs an empty hashset. 
     * * The actual bottom will initialize an empty HashMap and use the default initial capacity of 16 and load factor 0.75.
    * * Public hashset () {map = new hashmap<e,object> (); 
     /** * Constructs a new set containing the elements in the specified collection. 
     * * The actual bottom is to create a hashmap using the default load factor 0.75 and the initial capacity sufficient to contain all elements in the specified * collection. 
     * @param c where the elements will be stored in the collection in this set. */Public HashSet (collection< extends e> c) {map = new hashmap<e,object> ((int) (Math.max
        E ()/.75f) + 1, 16));
    AddAll (c); }/** * With the specified initialcapacity and LOadfactor constructs an empty hashset. 
     * * The actual bottom layer constructs an empty hashmap with the corresponding parameters. 
     * @param initialcapacity initial capacity. 
     * @param loadfactor loading factor. */public HashSet (int initialcapacity, float loadfactor) {map = new hashmap<e,object> (initialcapacit
    Y, Loadfactor); 
     /** * Constructs an empty hashset with the specified initialcapacity. 
     * * The actual bottom layer constructs an empty hashmap with the corresponding parameter and the load factor loadfactor to 0.75. 
     * @param initialcapacity initial capacity.
    * * Public hashset (int initialcapacity) {map = new hashmap<e,object> (initialcapacity); 
     /** * Constructs a new set of empty link hashes with the specified initialcapacity and loadfactor. 
     * This constructor is a package access, not public, but is actually a support for Linkedhashset. 
     * * The actual bottom layer is implemented with an empty Linkedhashmap instance with the specified parameters. 
     * @param initialcapacity initial capacity. 
     * @param loadfactor loading factor. 
     * @param dummy mark. */hashset (int initialcapacity, float loadfactor, Boolean dummy) {map = new linkedhashmap<e,object> (
    Initialcapacity, Loadfactor); }/** * Returns theAn iterator that iterates through the elements. 
     The order of the returned elements is not specific. 
     * * The bottom layer actually calls the keyset of the underlying hashmap to return all key. 
     * Visible elements in HashSet, only stored in the underlying HashMap key, * value uses a static final object identifier. 
     * @return The iterator that iterates through the elements in this set.
    * * @Override public iterator<e> iterator () {return Map.keyset (). iterator (); 
     /** * Returns the number of elements in this set (the capacity of the set). 
     * * the size () method of the underlying actual call to HashMap returns the number of entry, and the number of elements in the set is obtained. 
     * @return The number of elements in this set (the capacity of the set).
    */@Override public int size () {return map.size (); 
     /** * Returns True if this set does not contain any elements. 
     * * The underlying isempty () that actually invokes HashMap determines whether the hashset is empty. 
     * @return Returns True if this set does not contain any elements.
    * * @Override public boolean IsEmpty () {return map.isempty (); 
     /** * Returns True if this set contains the specified element. 
     * More specifically, returns True if and only if this set contains an e element that satisfies (O==null e==null:o.equals (e)) *. 
     * * The bottom of the actual call HashMap ContainsKey to determine whether to include the specified key. 
     * @param o The elements in this set have been tested. * @return If this SET contains the specified element, returns TRUE.
    * * @Override public boolean contains (Object o) {return map.containskey (o); 
     /** * If the specified element is not already contained in this set, the specified element is added. 
     * More specifically, if this set does not contain an element E2 that satisfies (E==null e2==null:e.equals (E2)) *, the specified element e is added to this set. 
     * If this set already contains the element, the call does not change the set and returns false. 
     * * The bottom actually puts the element as key into the HashMap. 
     * Since the HashMap put () method adds a Key-value pair, the key * in the entry of the newly placed HashMap is the same as the key in the set with entry (Hashcode () returns the same value and returns true through equals comparison). * The value of the newly added entry will overwrite the value of the original entry, but the key will not change anything, * so if you add an existing element to hashset, the newly added collection element will not be placed in the HashMap, * The original element is not 
     There will be any change, which satisfies the feature that the elements in set are not duplicated. 
     * @param e will be added to the elements in this set. 
     * @return Returns True if this set does not already contain the specified element.
    * * @Override Public boolean Add (e e) {return Map.put (E, PRESENT) ==null; 
     /** * If the specified element exists in this set, it is removed. * More specifically, if this set contains an element e that satisfies (O==null e==null:o.equals (e)), it is removed. Returns True * If this set already contains this element (or: Returns True if this set is changed because of a call). 
     (Once the call returns, this set no longer contains the element). * 
     * The Remove method that actually calls the HashMap at the bottom deletes the specified entry. 
     * @param o objects that need to be removed if they exist in this set. 
     * @return Returns True if the set contains the specified element.
    * * @Override public boolean remove (Object o) {return map.remove (o) ==present; /** * Removes all elements from this set. 
     When this call returns, the set will be empty. 
     * * The underlying clear method that actually calls HashMap clears all elements of the entry.
    */@Override public void Clear () {map.clear (); }
}


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.