Container-Set interface, HashSet (12)

Container-Set interface, HashSet (12)

  1. set interface: inherited from Collection, there is no new method in Set interface, and the method is consistent with Cellection. The method we learned through List in the front is still applicable in Set.

  2. Features: Disordered and non-repeatable . Disordered means that the elements in the Set have no index. We can only traverse and find them. Non-repeatable means that no duplicate elements are allowed to be added.

  3. Set commonly used implementation classes are: HashSet, TreeSet, etc., we generally use HashSet

  4. Hash algorithm principle : It is to take a modulo operation on a number through a hash formula, and the remaining remainder is placed under the index of an array correspondingly. If the remainder is the same, it is placed at the next index of this index.
    Insert picture description here

  5. There are many ways to use HashSet , which are basically the same as those of ArrayList.

    import java.util.HashSet;
    import java.util.Set;
    
    public class HashSetTest {
          
          
        public static void main(String[] args) {
          
          
            //实例化HashSet
            Set<String> set=new HashSet<>();
            //添加元素
            set.add("a");
            set.add("b1");
            set.add("c2");
            set.add("d");
            set.add("a");
    
    
            //获取元素,在Set容器中没有索引,所以没有对应的get(int index)方法
            //通过for-each循环遍历所有元素,来获取元素,且是无序的,重复元素的话,会去掉其中一个
            for (String str:set) {
          
          
                System.out.println(str);
            }
    
            System.out.println("----------------------------------");
            //删除元素
            boolean flag=set.remove("c2");
            System.out.println(flag);
            for (String str:set) {
          
          
                System.out.println(str);
            }
    
            System.out.println("-------------------------------");
            //返回元素的个数
            int size = set.size();
            System.out.println(size);
    
        }
    }
    
  6. Storage characteristics of HashSet :

    • HashSet is a collection that does not guarantee the order of elements and does not repeat , which is thread-unsafe. HashSet allows null elements
    • Unordered : The bottom layer in HashSet uses HashMap to store elements. The arrays and linked lists used at the bottom of HashMap implement element storage. When the elements are stored in the array, they are not stored in an orderly manner, but the hash value of the elements is calculated to determine the elements in the array.
    • No repetition : When the hash values ​​of two elements are calculated and get the same position in the array, the equals() method of the elements will be called to determine whether the two elements are the same . If the elements are the same, the element will not be added, and if they are different, the singly linked list will be used to save the element.

Insert picture description here

  1. Store custom objects through HashSet

    • Create Users object

      import java.util.Objects;
      
      public class Users {
              
              
          private String username;
          private int userage;
      //定义有参构造器
          public Users(String username, int userage) {
              
              
              this.username = username;
              this.userage = userage;
          }
      //定义无参构造器
          public Users() {
              
              
          }
      //重写 hashCode和equals方法
          @Override
          public boolean equals(Object o) {
              
              
              System.out.println("equals............");
              if (this == o) return true;
              if (o == null || getClass() != o.getClass()) return false;
              Users users = (Users) o;
              return userage == users.userage &&
                      Objects.equals(username, users.username);
          }
      
          @Override
          public int hashCode() {
              
              
              return Objects.hash(username, userage);
          }
      //定义get、set方法
          public String getUsername() {
              
              
              return username;
          }
      
          public void setUsername(String username) {
              
              
              this.username = username;
          }
      
          public int getUserage() {
              
              
              return userage;
          }
      
          public void setUserage(int userage) {
              
              
              this.userage = userage;
          }
      
          @Override
          public String toString() {
              
              
              return "Users{" +
                      "username='" + username + '\'' +
                      ", userage=" + userage +
                      '}';
          }
      }
      
      
    • Store the Users object in HashSet

      import java.util.HashSet;
      import java.util.Set;
      
      public class HashSetTest {
              
              
          public static void main(String[] args) {
              
              
              //实例化HashSet
              Set<String> set=new HashSet<>();
              //添加元素
              set.add("a");
              set.add("b1");
              set.add("c2");
              set.add("d");
              set.add("a");
      
      
              //获取元素,在Set容器中没有索引,所以没有对应的get(int index)方法
              //通过for-each循环遍历所有元素,来获取元素,且是无序的,重复元素的话,会去掉其中一个
              for (String str:set) {
              
              
                  System.out.println(str);
              }
      
              System.out.println("----------------------------------");
              //删除元素
              boolean flag=set.remove("c2");
              System.out.println(flag);
              for (String str:set) {
              
              
                  System.out.println(str);
              }
      
              System.out.println("-------------------------------");
              //返回元素的个数
              int size = set.size();
              System.out.println(size);
      
              System.out.println("----------------------------------");
              //实例化HashSet
              Set<Users> set1= new HashSet<>();
              Users u=new Users("oldlu",18);
              Users u1=new Users("oldlu",18);
              set1.add(u);
              set1.add(u1);
              System.out.println(u.hashCode());
              System.out.println(u1.hashCode());
              for (Users users:set1){
              
              //因为哈希值的不同,所以会对象两个我们以为相同的两个对象
                                      // /怎么解决,我们去Users类重写HashCode方法
                                      //重写完HashCode方法之后,打印出的哈希值是相同的,然后他们对相同的数取模运算,余数肯定是相同的
                                      //然后去用到equals()方法判断,就会返回的是true,所以就只会返回一个对象。
                                      //如果以后我们存取Hastset自定义的时候,如果想让他具备不重复的特点,那么我们一定要在自定义对象当中重写HashCode和equals方法
      
                  System.out.println(users);
              }
      
          }
      }
      
      
  2. Analysis of the underlying source code of HashSet :

    • Use Ctrl+left mouse button to enter the source code of set1= new HashSet<>(); HashSet, look at its inheritance structure and member variables first.

      public class HashSet<E>
          extends AbstractSet<E>//继承AbstractSet<E>类,实现Set<E>接口
          implements Set<E>, Cloneable, java.io.Serializable
      {
              
              
          static final long serialVersionUID = -5024744406713321676L;
      
          private transient HashMap<E,Object> map;//一个map变量,map是双例集合,用的是K-v结构,所以HashMap<E,Object>,E作为Key值,Object作为Value值
      
          // Dummy value to associate with an Object in the backing Map
          private static final Object PRESENT = new Object();//PRESENT是一个Object()对象
      
    • Then look at the parameterless structure

          /**
           * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
           * default initial capacity (16) and load factor (0.75).
           */
          public HashSet() {
              
              
              map = new HashMap<>();//实现一个HashMap对象来存放元素
          }
      
    • When we call the add method , first use Ctrl+left mouse button to enter the source code, and use Ctrl+Alt to click add to select the HashSet interface implementation class and then enter the source code

      public boolean add(E e) {
              
              
          return map.put(e, PRESENT)==null;//当我们调用add方法时,直接将元素放到map当中,在map当中添加元素的方法时put,e代表的是Hashmap当中的Key,所以所有的元素都会放在Hashmap当中的Key来存储,Value随便给一个值来存储就可以了
      }
      

Guess you like

Origin blog.csdn.net/Xun_independent/article/details/114708791