天天看點

java集合之Set:HashSet、TreeSet

HashSet與TreeSet的比較。HashSet去重。

package com.qianfeng.test;

import java.util.HashSet;

public class Demo9 {

public static void main(String[] args) {

    /*
     * Set:無序的,不可重複的
     *      HashSet:底層是哈希表,線程不安全的
     *      TreeSet:底層是二叉樹,線程不安全的
     * 
     * HashSet實作去重的方法:是通過調用元素内部的hashCode和equals方法實作去重.首先會調用hashCode方法,比較兩個元素的
     * 哈希碼值,如果哈希碼值不同直接認為是兩個對象,停止比較.如果相同,再去使用equals比較.傳回true認為是一個對象,傳回false認為是
     * 兩個對象.
     * 
     * TreeSet:實作去重和排序的方式:1.讓元素去實作Comparable接口,重寫compareTo方法
     *  2.建立比較器類,讓他實作Comparetor接口,重寫compare方法,再将比較器對象作用于TreeSet,内部的元素會按照比較器進行比較.
     */

    /*
     * 先講HashSet
     * HashSet實作去重的方法:是通過調用元素内部的hashCode和equals方法實作去重.首先會調用hashCode方法,比較兩個元素的
     * 哈希碼值,如果哈希碼值不同直接認為是兩個對象,停止比較.如果相同,再去使用equals比較.傳回true認為是一個對象,傳回false認為是
     * 兩個對象.
     * 
     * 總結:1.hashSet隻能實作去重,不能排序
     * 2.對于自定義的類要想按照自己制定的規則去重,必須重寫hashcode和equals方法
     */
    HashSet set = new HashSet<>();
    /*
     * 在add内部實作的去重的功能.預設調用字元串的hashCode和equals方法.
     * 在String中是重寫了hashCode和equals方法,是以可以保證在進行比較的時候,比較的是内容.
     */
    set.add("java1");
    set.add("java4");
    set.add("java2");
    set.add("java5");
    set.add("java2");
    System.out.println(set);
    /*
     * 列印結果:[java5, java4, java2, java1]
     * 說明:實作了去重
     */

    //執行個體:将Person1的對象存入Set1,按照姓名和年齡比較
    HashSet set1 = new HashSet<>();
    set1.add(new Person1("bingbing1", 18));
    set1.add(new Person1("bingbing2", 18));
    set1.add(new Person1("bingbing3", 183));
    set1.add(new Person1("bingbing3", 183));
    set1.add(new Person1("bingbing4", 186));
    System.out.println(set1);
    /*
     * 列印結果:[Person1 [name=bingbing4, age=186], Person1 [name=bingbing1, age=18], Person1 [name=bingbing2, age=18], Person1 [name=bingbing3, age=183]]
     * 說明:對自定義的類實作了去重
     */
}
           

}

class Person1{

String name;
int age;
public Person1(String name, int age) {
    super();
    this.name = name;
    this.age = age;
}
@Override
public String toString() {
    return "Person1 [name=" + name + ", age=" + age + "]";
}

//重寫hashCode方法
@Override
public int hashCode() {

    return name.hashCode()+age*1000;
}

//重寫equals方法,制定自己的比較規則:隻要年齡和姓名相同就認為是同一個人
@Override
public boolean equals(Object obj) {
    //容錯處理
    if (!(obj instanceof Person1)) {
        throw new ClassCastException("類型轉化異常");
    }

    //向下轉型
    Person1 person = (Person1)obj;
    return this.name.equals(person.name) && this.age == person.age;
}
           

}

TreeSet實作去重和排序:預設排序

package com.qianfeng.test;

import java.util.HashSet;

import java.util.TreeSet;

public class Demo10 {

public static void main(String[] args) {

    // TreeSet:實作去重和排序的方式:
    //1.讓元素去實作Comparable接口,重寫compareTo方法------預設排序
    //2.建立比較器類,讓他實作Comparetor接口,重寫compare方法,再将比較器對象作用于TreeSet,
        //内部的元素會按照比較器進行比較.---人工排序

    //學習第一種
    //1.讓元素去實作Comparable接口,重寫compareTo方法------預設排序
    TreeSet set = new TreeSet<>();
    //使用TreeSet在存儲字元串的時候自動實作了排序和去重
    //因為在add方法中調用了Comparable接口的compareTo方法
    //預設是按照升序字典順序排序
    set.add("java1");
    set.add("java4");
    set.add("java2");
    set.add("java5");
    set.add("java2");
    System.out.println(set);
    /*
     * 列印結果:[java1, java2, java4, java5]
     * 說明:實作了去重和排序
     */

    //執行個體:将Person2的對象存入TreeSet,按照姓名和年齡比較
    TreeSet set1 = new TreeSet<>();
    set1.add(new Person2("bingbing1", 18));
    set1.add(new Person2("bingbing2", 18));
    set1.add(new Person2("bingbing3", 183));
    set1.add(new Person2("bingbing3", 183));
    set1.add(new Person2("bingbing0", 17));
    System.out.println(set1);
}
           

}

//自定義的類實作Comparable接口

class Person2 implements Comparable{

String name;
int age;
public Person2(String name, int age) {
    super();
    this.name = name;
    this.age = age;
}
@Override
public String toString() {
    return "Person2 [name=" + name + ", age=" + age + "]";
}

@Override
//自己制定的規則:按照年齡和姓名比較
/*
 *傳回正數,代表前面的比後面的大
 *傳回0,代表前後相等
 *傳回負數,代表前面的比後面的小
 */
public int compareTo(Object o) {
    if (!(o instanceof Person2)) {
        throw new ClassCastException("類型轉換錯誤");
    }

    //向下轉型
    Person2 person2 = (Person2)o;

    //先按照年齡比較,年齡相同再去比姓名
    int num = age-person2.age;
    return num==0?name.compareTo(person2.name):num;
}
           

}

TreeSet實作去重和排序:建立比較器類

package com.qianfeng.test;

import java.util.Comparator;

import java.util.TreeSet;

//2.建立比較器類,讓他實作Comparetor接口,重寫compare方法,再将比較器對象作用于TreeSet,

//内部的元素會按照比較器進行比較.—人工排序

public class Demo11 {

public static void main(String[] args) {

    //2.建立比較器對象,并指定給存儲元素的TreeSet
    ComWithLength comWithLength = new ComWithLength();

    TreeSet set = new TreeSet<>(comWithLength);
    //使用TreeSet在存儲字元串的時候自動實作了排序和去重

    set.add("java1111111111111");
    set.add("java422");
    set.add("java2456");
    set.add("java523535");
    set.add("java2456");
    System.out.println(set);

    //執行個體:将Person3的對象存入TreeSet,按照姓名和年齡排,先按照年齡排,再按照姓名排.
    ComWithLength comWithLength1 = new ComWithLength();
    ComWithPerson3 comWithPerson3 = new ComWithPerson3();
    TreeSet set1 = new TreeSet<>(comWithPerson3);
    set1.add(new Person3("bingbing1", 18));
    set1.add(new Person3("bingbing2", 18));
    set1.add(new Person3("bingbing3", 183));
    set1.add(new Person3("bingbing3", 183));
    set1.add(new Person3("bingbing0", 17));
    System.out.println(set1);

}
           

}

//1.建立比較器類

class ComWithLength implements Comparator{

@Override
public int compare(Object o1, Object o2) {
    //容錯處理
    if (!(o1 instanceof String)) {
        throw new ClassCastException("類型轉換異常");
    }
    if (!(o2 instanceof String)) {
        throw new ClassCastException("類型轉換異常");
    }
    //向下轉型
    String s1 = (String)o1;
    String s2 = (String)o2;

    //要求按照字元串的長度對字元串進行排序--從短到長,當長度相同的時候,按照字典排序
    int num = s1.length()-s2.length();
    return num==0?s1.compareTo(s2):num;
}
           

}

class ComWithPerson3 implements Comparator{

@Override
public int compare(Object o1, Object o2) {
    //容錯處理
    if (!(o1 instanceof Person3)) {
        throw new ClassCastException("類型轉換異常");
    }
    if (!(o2 instanceof Person3)) {
        throw new ClassCastException("類型轉換異常");
    }
    //向下轉型
    Person3 person1 = (Person3)o1;
    Person3 person2 = (Person3)o2;

    //先按照年齡比較,年齡相同再去比姓名
    int num = person1.age-person2.age;
    return num==0?person1.name.compareTo(person2.name):num;
}
           

}

class Person3{

String name;
int age;
public Person3(String name, int age) {
    super();
    this.name = name;
    this.age = age;
}
@Override
public String toString() {
    return "Person3 [name=" + name + ", age=" + age + "]";
}
           

}