【java】Establecer explicación detallada

Configuraciones comunes del comando set

        Las funciones de cada opción son las siguientes:

El acceso al conjunto está desordenado y los elementos son únicos.

Demostración de código:

public static void demo1() {
    HashSet<String> hs = new HashSet<>();	//创建HashSet对象
    boolean b1 = hs.add("a");
    boolean b2 = hs.add("a");		//当向set集合中存储重复元素的时候返回为false
   
    hs.add("b");
    hs.add("c");
    hs.add("d");
    System.out.println(hs);			//[d, b, c, a] 存取无序 并且去掉了重复元素
    System.out.println(b1);			//true
    System.out.println(b2);			//false	

    for (String string : hs) {		//只要能用迭代器迭代的,就可以使用增强for循环遍历
        System.out.println(string);
    }
}

        Para garantizar la unicidad de un elemento, el elemento debe anular dos métodos: uno es hashCode () y el otro es igual (). En el proceso de almacenamiento de elementos, HashSet primero llamará al valor hashCode() del elemento para ver si su valor hash es el mismo que el valor hash del elemento ya almacenado en HashSet. Si es diferente: se agregará directamente al conjunto; si es el mismo: entonces continúe llamando a iguales () de los elementos y compare estos elementos con el mismo valor hash en secuencia. Si hay uno que devuelve verdadero, entonces repítelo sin agregarlo; si los resultados de la comparación son todos falsos, entonces agrégalo sin repetirlo. Para reducir el número de comparaciones de iguales y mejorar la eficiencia, en general, los objetos con diferentes atributos deben tener diferentes valores de hashCode (). Entonces, ¿cómo reescribir iguales () y hashCode ()? Eclipse puede generarlo automáticamente.

Demostración de código:

        

public static void main(String[] args) {
    HashSet<Person> hs = new HashSet<>();
    hs.add(new Person("张三", 23));
    hs.add(new Person("张三", 23));
    hs.add(new Person("李四", 24));
    hs.add(new Person("李四", 24));
    hs.add(new Person("李四", 24));
    hs.add(new Person("李四", 24));
		
	System.out.println(hs);//Person重写了equals()方法和hashCode()方法,所以 hs 去除了重复的元素
}
public class Person {	//Person里面 Eclipse自动生成了 equals()方法和hashCode()方法
    private String name;
    private int age;
    public Person() {
        super();			
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }	
    
    /*
	* 为什么是31?
	* 1,31是一个质数,质数是能被1和自己本身整除的数
	* 2,31这个数既不大也不小
	* 3,31这个数好算,2的五次方-1,2向左移动4位
	*/
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)				//调用的对象和传入的对象是同一个对象
            return true;				//直接返回true
        if (obj == null)				//传入的对象为null
            return false;				//返回false
        if (getClass() != obj.getClass())//判断两个对象对应的字节码文件是否是同一个字节码
            return false;				//如果不是直接返回false
        Person other = (Person) obj;		//向下转型
        if (age != other.age)				//调用对象的年龄不等于传入对象的年龄
            return false;				//返回false
        if (name == null) {				//调用对象的姓名为null
            if (other.name != null)			//传入对象的姓名不为null
                return false;			//返回false
        } else if (!name.equals(other.name))		//调用对象的姓名不等于传入对象的姓名
            return false;				//返回false
        return true;					//返回true
    }		
}

        

LinkedHashSet: la clase principal directa es HashSet

Características: El acceso es ordenado y los elementos almacenados no se pueden repetir.

Demostración de código:

        

LinkedHashSet<String> lhs = new LinkedHashSet<>();
lhs.add("a");
lhs.add("a");
lhs.add("a");
lhs.add("a");
lhs.add("b");
lhs.add("c");
lhs.add("d");

System.out.println(lhs);//[a,b,c,d]  去除了重复的元素,同时又保证了存取有序

TreeSet: el elemento es único y lo más importante es ordenar los elementos.

Método 1: Deje que la clase donde se encuentra el elemento implemente la interfaz Comparable, anule el método CompareTo() y agregue elementos según el valor de retorno de CompareTo()

    Devuelve un número positivo: suma al lado derecho del árbol binario.
    Devuelve un número negativo: suma al lado izquierdo del árbol binario
    . Devuelve 0: duplicado, no suma.

Ejemplo:
        

public static void demo2() {
    TreeSet<Person> ts = new TreeSet<>();
    ts.add(new Person("zhangsan", 23));
    ts.add(new Person("lisi", 13));
    ts.add(new Person("wangwu", 33));
    ts.add(new Person("zhaoliu", 43));
    ts.add(new Person("aaaa", 53));
    System.out.println(ts);
}
public class Person implements Comparable<Person> {
    private String name;
    private int age;
    public Person() {
        super();
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    /*
    //1):按照年龄排(先比较年龄后比较姓名)
    public int compareTo(Person o) {		
    	//this 是集合即将存入的元素, o 是集合已经存入的元素
    	int num = this.age - o.age;	//年龄是比较的主要条件
    	return num == 0 ? this.name.compareTo(o.name) : num;	//姓名是比较的次要条件
    }
    */

    /*
    //2):按照姓名排(先比较姓名后比较年龄)
    public int compareTo(Person o) {
    	int num = this.name.compareTo(o.name);		//姓名是主要条件
   		return num == 0 ? this.age - o.age : num;	//年龄是次要条件
    }
    */

    //3):按照姓名长度排(先比较姓名长度 后比较姓名内容 后比较年龄)
    public int compareTo(Person o) {	
        int length = this.name.length() - o.name.length();	//比较长度为主要条件
        int num = length == 0 ? this.name.compareTo(o.name) : length;//比较内容为次要条件
        return num == 0 ? this.age - o.age : num;//比较年龄为次要条件
    }	
}

        

Método 2: al crear un objeto TreeSet utilizando el método de construcción parametrizado de TreeSet, pase un comparador Comparador. Al agregar elementos a TreeSet, los elementos se agregan en función del valor de retorno del método compare () del comparador.

    Devuelve un número positivo: suma al lado derecho del árbol binario.
    Devuelve un número negativo: suma al lado izquierdo del árbol binario
    . Devuelve 0: duplicado, no suma.

Demostración de código:
        

public static void demo3() {
    //在构造函数中传入比较器后 就不用再让Person实现Comparable接口了
    TreeSet<Person> ts = new TreeSet<>(new Comparator<Person>() {	
        //3):按照姓名长度排(先比较姓名长度 后比较姓名内容 后比较年龄)
        @Override
        public int compare(Person o1, Person o2) {//o1是即将存入的元素  o2是已经存入集合的元素
            //比较长度为主要条件
            int length = o1.getName().length() - o2.getName().length();	
            //比较内容为次要条件
            int num = length == 0 ? o1.getName().compareTo(o2.getName()) : length;	
            return num == 0 ? o1.getAge() - o2.getAge() : num;
        }

        /*
		//2):按照姓名排(先比较姓名后比较年龄)
		public int compare(Person o1, Person o2) {
			int num = o1.getName().compareTo(o2.getName());
			return num == 0 ? o1.getAge() - o2.getAge() : num;
		}
		*/

        /*
		//1):按照年龄排(先比较年龄后比较姓名)
		public int compare(Person o1, Person o2) {
			int num = o1.getAge() - o2.getAge();
			return num == 0 ? o1.getName().compareTo(o2.getName()) : num;
		}
		*/
    });
    ts.add(new Person("zhangsan", 23));
    ts.add(new Person("lisi", 13));
    ts.add(new Person("wangwu", 33));
    ts.add(new Person("zhaoliu", 43));
    ts.add(new Person("aaaa", 53));
    System.out.println(ts);
}

Análisis del código fuente de elementos de almacenamiento y clasificación de TreeSet

        Cuando TreeSet almacena elementos, primero determinará si existe un comparador (es decir, determinará si el comparador es nulo). Si existe, se le pedirá al comparador que llame al método compare (T t1, T t2) para comparar el próximo elementos en secuencia. El valor almacenado y el valor ya almacenado en la colección TreeSet. Si se devuelve un número positivo: póngalo en el lado derecho del árbol binario; si se devuelve un número negativo: póngalo en el lado izquierdo del árbol binario. árbol binario; si devuelve 0: no sumar. Si no existe: la capa inferior promoverá automáticamente el elemento que se almacenará a un objeto de tipo Comparable (por lo tanto, si no hay un comparador, la clase donde se encuentra el elemento no implementa la interfaz Comparable y el tipo será reportado al realizar la promoción automática. Error de conversión), y dejar que el objeto llame al método CompareTo(T t) y lo compare con los elementos que se han almacenado en la colección TreeSet en secuencia. Si se devuelve un número positivo: póngalo el lado derecho del árbol binario; si se devuelve un número negativo: colóquelo en el lado izquierdo del árbol binario; si devuelve 0: no sume. Por lo tanto, si se utilizan ambos métodos al mismo tiempo, la capa inferior dará prioridad al uso del segundo método (el método comparador).

Análisis de fragmentos de código fuente:
        

        

 public V put(K key, V value) {		//key则是TreeSet即将存入的元素
     Entry<K,V> t = root;		//获取TreeSet中已存入的元素列表也就是 t

     /*此处有代码省略*/
     
	 //comparator是一个成员变量,初始值是null,如果TreeSet构造方法中传入了比较器
     //则comparator就不再是null
     Comparator<? super K> cpr = comparator;
     if (cpr != null) {	//如果有比较器 就使用比较器来比较
     	do {
             parent = t;
             cmp = cpr.compare(key, t.key);	//让比较器 cpr 去调用compare(T t1, T t2)方法,去依次比较即将存入的值 key 和已经存入TreeSet集合的值 t.key
             if (cmp < 0)			//如果返回负数
                 t = t.left;			//往二叉树左侧放
             else if (cmp > 0)		//如果返回正数
                 t = t.right;		//往二叉树右侧放
             else				//如果返回 0
                 return t.setValue(value);	//不添加
         } while (t != null);
     } else {				//如果没有比较器 则使用自然排序来比较
         if (key == null)
             throw new NullPointerException();
         Comparable<? super K> k = (Comparable<? super K>) key;	//把即将存入的元素 key 自动提升为Comparable类型的对象 k (所以如果没有比较器的情况下,元素所在的类没有实现Comparable接口,在做自动提升类型的时候就会报类型转换错误),
         do {
             parent = t;
             cmp = k.compareTo(t.key);	//让即将存入的元素 k 调用CompareTo(T t)方法,和已经存入TreeSet集合的元素 t.key 依次比较
             if (cmp < 0)			//如果返回负数
                 t = t.left;			//往二叉树左侧放
             else if (cmp > 0)		//如果返回正数
                 t = t.right;		//往二叉树右侧放
             else				//如果返回 0
                 return t.setValue(value);	//不添加
         } while (t != null);
     }

     /*此处有代码省略*/

 }

        Caso 1: escriba un programa para obtener 10 números aleatorios del 1 al 20, lo que requiere que los números aleatorios no se puedan repetir. Y envíe el número aleatorio final a la consola.

        

/** - 分析:
  	- 1,有Random类创建随机数对象
    - 2,需要存储10个随机数,而且不能重复,所以我们用HashSet集合
    - 3,如果HashSet的size是小于10就可以不断的存储,如果大于等于10就停止存储
    - 4,通过Random类中的nextInt(n)方法获取1到20之间的随机数,并将这些随机数存储在HashSet集合中
    - 5,遍历HashSet
      */
public static void main(String[] args) {

    //1,有Random类创建随机数对象
    Random r = new Random();

    //2,需要存储10个随机数,而且不能重复,所以我们用HashSet集合
    HashSet<Integer> hs = new HashSet<>();

    //3,如果HashSet的size是小于10就可以不断的存储,如果大于等于10就停止存储
    while(hs.size() < 10) {

        //4,通过Random类中的nextInt(n)方法获取1到20之间的随机数,并将这些随机数存储在HashSet集合中
        hs.add(r.nextInt(20) + 1);
    }

    // 5,遍历HashSet
    for (Integer integer : hs) {
        System.out.println(integer);
    }

}

        Caso 2: En una colección se almacenan cadenas desordenadas y repetidas, defina un método para ordenarlas (orden lexicográfico) y los duplicados no se pueden eliminar.

        

/** - 分析:
    - 1,定义一个List集合,并存储重复的无序的字符串
    - 2,定义方法对其排序保留重复
    - 3,打印List集合
 */
public static void main(String[] args) {
	//1,定义一个List集合,并存储重复的无序的字符串
    ArrayList<String> list = new ArrayList<>();
    list.add("aaa");        
    list.add("aaa");        
    list.add("ccc");        
    list.add("ddd");        
    list.add("fffffffffff");        
    list.add("heima");        
    list.add("itcast");        
    list.add("bbbb");        
    list.add("aaa");        
    list.add("aaa");                
    
    //2,定义方法对其排序保留重复       
    sort(list);                
    //3,打印list        
    System.out.println(list);
}       
/*     
	* 定义方法,排序并保留重复     
	* 分析:     
	* 1,创建TreeSet集合对象,因为String本身就具备比较功能,但是重复不会保留,所以我们用比较器
	* 2,将list集合中所有的元素添加到TrreSet集合中,对其排序,保留重复 
	* 3,清空list集合
	* 4,将TreeSet集合中排好序的元素添加到list中 
*/    
public static void sort(List<String> list) {
    //1,创建TreeSet集合对象,因为String本身就具备比较功能,但是重复不会保留,所以我们用比较器      
    TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
   		@Override            
    	public int compare(String s1, String s2) {
            int num = s1.compareTo(s2);
            //比较内容为主要条件
            return num == 0 ? 1 : num; //保留重复            
        }        
    });     
    //2,将list集合中所有的元素添加到TrreSet集合中,对其排序,保留重复
    ts.addAll(list);       
    //3,清空list集合        
    list.clear();        
    //4,将TreeSet集合中排好序的元素添加到list中        
    list.addAll(ts);    
}

        

Supongo que te gusta

Origin blog.csdn.net/m0_73367097/article/details/132420160
Recomendado
Clasificación