Variable parameters of set interface, hash table, hash value, HashSet, LinkedHashSet, method in java

set interface:

Like the list interface, the set interface is inherited from the Collection interface, and its methods are basically the same as those in the Collection interface. Features: Duplicate elements are not allowed to be stored, and elements have no index. It mainly has two implementation classes: HashSet (has a hash table structure, is actually a HashMap instance, it has no order, but the query speed is very fast, and the bottom layer is not synchronized) and LinkedHashSet

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

// set接口:继承于Collection接口,不允许存储重复元素,且没有索引,因此不能使用带索引的方法,也不能使用普通的for遍历
// set接口主要有两个实现类:HashSet和
// 1.HashSet特点:1.不允许存储重复元素 2.没有索引,不能使用带索引的方法,也不能使用普通的for遍历 3.无序的集合,存取元素的顺序可能不同 4.底层是一个哈希表结构(查询速度非常快)
public class setInterfaceClass {
    
    
    public static void main(String[] args) {
    
    
        // 使用多态的方式创建一个HashSet集合:
        Set<Integer> st = new HashSet<Integer>();
        // 使用add方法向集合中添加元素:
        st.add(1);
        st.add(2);
        st.add(2);
        st.add(4);
        System.out.println(st); // [1, 2, 3, 4]
        // 遍历st集合:不能使用for遍历没有索引的集合:一般使用迭代器或增强for遍历没有索引的集合:
        // for (int i = 0; i < st.size();i++) {
    
    
        //    System.out.println(st[i]);
        //}
        Iterator<Integer> it = st.iterator();
        while (it.hasNext()) {
    
    
            int num = it.next();
            System.out.println(num); // 分别打印出了每个元素,但是2只打印了一次,因为存元素时不会存入重复的元素
        }
        for (int i : st) {
    
    
            System.out.println(i); // 分别打印出了每个元素,但是2只打印了一次,因为存元素时不会存入重复的元素
        };
    }
}

Hash table:

The structure of the HashSet collection storing data is to use a hash table, so what is a hash table? To understand hash tables, first understand hash values.

Hash value : a decimal integer, randomly given by the system (actually the address value of the object, but not a physical address, but a simulated address, there is a hashCode method in the Object class to obtain the hash value of the object) ,

Define a class that inherits Object:

// 定义一个TestClass类并继承Object
public class TestClass extends Object{
    
    
    // 点进Object查找hashCode方法可以看到源码:public native int hashCode(); 此方法没有方法体,而是有一个native,表示该方法调用了本地系统方法
}

Create an object using the TestClass class and use the hashCode method:

// 哈希值:一个由系统随机给出的对象整数地址值,hashCod方法可以返回这个哈希值:
public class hashCodeMethodsClass {
    
    
    public static void main(String[] args) {
    
    
        // 创建一个TestClass类的对象,又因为TestClass类继承了Object,因此可以调用hashCode方法:
        TestClass tc = new TestClass();
        int hashValue = tc.hashCode();
        System.out.println(hashValue); // 1967205423 ,每次执行都会得到不同的值

        TestClass tc2 = new TestClass();
        int hashValue2 = tc2.hashCode();
        System.out.println(hashValue2); // 42121758 ,每次执行都会得到不同的值
        System.out.println(tc == tc2); // false
 
        // 如何我们重写hashCode方法,那么返回值就一直是一个定值,虽然返回值的哈希值是相同的,但是这两个对象也是不相等的,因为物理地址不同

        // String类的哈希值:
        String s1 = new String("abc");
        String s2 = new String("abc");
        System.out.println(s1.hashCode()); // 96354
        System.out.println(s2.hashCode()); // 96354
        System.out.println(s1 == s2); // false

        // 字符串不相同,哈希值也是有可能相同的,如:
        System.out.println("重地".hashCode()); // 1179395
        System.out.println("通话".hashCode()); // 1179395
    }
}

Hash table structure:

Before jdk1.8 hash table = array + linked list, after jdk1.8 hash table = array + red-black tree (to improve query speed)
insert image description here
The principle that the set collection cannot store duplicate elements:

import java.util.HashSet;

// set集合不允许存储重复元素的原理:
public class setNoRepet {
    
    
    public static void main(String[] args) {
    
    
        HashSet<String> st = new HashSet<String>();
        String s1 = new String("abc");
        String s2 = new String("abc");

        st.add(s1);
        st.add(s2);
        st.add("重地");
        st.add("通话");
        st.add("abc");

        System.out.println(st); // [重地, 通话, abc] ,每次添加元素底层都会调用hashCode计算哈希值,并将这个哈希值水平存到数组中,如果有相同的哈希值元素被添加,那么会继续调用equals方法进一步比较两个元素是否相同,如果相同则不会存储,否则会在垂直方向将元素存到对应哈希值下面
    }
}

insert image description here
HashSet stores custom type elements:

When storing custom elements in the HashSet, you need to rewrite the hashCode and equals methods in the object and create your own comparison method to ensure that the objects in the HashSet collection are unique.

Custom class:

import java.util.Objects;

public class Person {
    
    
    private String name;
    private int age;

    public void setName(String name) {
    
    
        this.name = name;
    }

    public Person() {
    
    
    }

    //  重写equals和hashCode方法代码可以alt+insert自定生成:
    @Override
    public boolean equals(Object o) {
    
    
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
    
    
        return Objects.hash(name, age);
    }

    public Person(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    public String getName() {
    
    
        return name;
    }

    public int getAge() {
    
    
        return age;
    }
}

Use HashSet to store custom elements:

import java.util.HashSet;

// HashSet存储自定义元素:set集合存储元素唯一,以后如果要在HasHset中存储元素,一定要覆重写hashCode和equals方法:
public class customElementSaveHashSet {
    
    
    public static void main(String[] args) {
    
    
        Person p1 = new Person("小明",12);
        Person p2 = new Person("小明",12);
        Person p3 = new Person("小红",22);

        HashSet<Person> ps = new HashSet<>();
        ps.add(p1);
        ps.add(p2);
        ps.add(p3);
        System.out.println(p1.hashCode()); //1967205423
        System.out.println(p2.hashCode()); //42121758
        System.out.println(p3.hashCode()); //20671747
        System.out.println(ps); // [Person@13b6d03, Person@282ba1e, Person@75412c2f], 存进去了两个对象

        // 上面是没有重写hashCode方法和equals方法,会存三个值进去,下面是重写了Person类中的hashCode和equals方法的结果:
        System.out.println(p1.hashCode()); //23458766
        System.out.println(p2.hashCode()); //23458766
        System.out.println(p3.hashCode()); //23653828
        System.out.println(ps); // [Person@165f3ce, Person@168edc4]
    }
}

A LinkedHashSet collection:

LinkedHashSet is an implementation of a hash table and linked list with a predictable iteration order set interface. It inherits from the HashSet collection. The difference from hashSet is that LinkedHashSet maintains a double-linked list that runs on all entries. This linked list defines the iteration order. (According to the order in which elements are inserted into the set, and the order of insertion is not affected by reinserting elements in the set)

import java.util.HashSet;
import java.util.LinkedHashSet;

// LinkedHashSet继承于HashSet集合,底层是一个哈希表(数组+链表/红黑树)和链表构成,可以看出是双链,其中一条是记录元素存储顺序的。
public class LinkedHashSetClass {
    
    
    public static void main(String[] args) {
    
    
        // 创建一个HashSet集合:
        HashSet<String> st = new HashSet<>();
        st.add("WWW");
        st.add("abc");
        st.add("abc");
        st.add("hello");
        System.out.println(st); // [abc, WWW, hello] ,可以看到遍历的顺序和存储的顺序是不一致且不允许重复存储的。

        // 创建一个LinkedHashSet集合:
        LinkedHashSet<String> ls = new LinkedHashSet<>();
        ls.add("WWW");
        ls.add("abc");
        ls.add("abc");
        ls.add("hello");
        System.out.println(ls); // [WWW, abc, hello] ,可以看到与HashSet集合不一致的是:元素存储迭代是有顺序的,且也是不重复
    }
}

variable parameter:

After jdk1.5, if the defined method needs to receive multiple parameters, and the parameter data types are consistent, then we can simplify the writing of its incoming parameters: (parameter type...formal parameter name), when the parameter type of the method is determined and the parameter Variable parameters can be used when the number is uncertain. The variable parameter is actually an array (passing several parameters will create an array with several elements) and store each parameter, such as:

public class VarParamClass {
    
    
    public static void main(String[] args) {
    
    
        getSum(); // 0
        getSum(2,4); // 2
    }
    // 一个方法的可变参数列表只能有一个参数,也就是说可变的参数只能有一个:
    public static void getSum(int...num) {
    
    
        System.out.println(num.length);
    };

    // 如果有多个参数,其中有一个可变参数,那么这个可变参数放到最后面试可行的:
    public static void getResult(String s,int n, Boolean b, int...num) {
    
    
        System.out.println(num.length);
    };

    // 当有多个参数时,可变参数不能放到其他位置,只能放到末尾:
    // public static void getReut(int...num,String s,int n, Boolean b) {
    
    
    //    System.out.println(num.length);
    //};
}

Tips: The pictures and other materials in this article come from the Internet. If there is any infringement, please send an email to the mailbox: [email protected] to contact the author to delete it.
Author: sea of ​​bitterness

Guess you like

Origin blog.csdn.net/weixin_46758988/article/details/128154484