Set接口中的HashSet,LinkedHashSet,TreeSet

Posted afangfang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Set接口中的HashSet,LinkedHashSet,TreeSet相关的知识,希望对你有一定的参考价值。

TestSet

package com.aff.coll;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;

import org.junit.Test;

/*
    Collection接口
              |----Set接口:存储无序的,不可重复的元素,Set中常有的方法都是Collection下定义的
                              |----HashSet(主要实现类)
                              |----LinkedHashSet
                              |----TreeSet
 */
public class TestSet {
    /*
     1.set存储的元素是无序的,不可重复的,无序性:无序性 != 随机性 真正的无序性,指的是元素在底层存储的位置是无序的 
     2.不可重复性:当Set中添加相同的元素的时候,后面的这个元素添加不进去
     3.Set中元素存储方式:使用哈希算法。
                            当向Set中添加对象时,首先调用此对象所在类的hashCode()方法,
                            计算此对象的哈希值,此哈希值决定Set中的存储位置,若此位置之前
                            没有对象存储,则这个对象直接存储到此位置。若此位置已有对象存储,
                            在通过equals()比较这两个对象是否相同。如果相同,后一个对象就不能再添加进来
                            万一返回false,都存储(不建议如此)
     要求:hashCode()方法要与equals()方法一致。       
     说明:要求添加进Set中的元素所在的类,一定要重写equals()和hashCode()方法,进而保证Set中元素不可重复性
        
     */
    //HashSet() 
    @Test
    public void testHashSet() {
        Set set = new HashSet();
        set.add(123);
        set.add(456);
        set.add(new String("AA"));
        set.add(new String("BB"));
        set.add(null);
        Person p1 = new Person("GG", 23);
        Person p2 = new Person("GG", 23);
        set.add(p1);
        set.add(p2);
        System.out.println(set.size());// 5
        System.out.println(set);// [AA, BB, null, 456, 123]
                               // 由于HashSet重写了toString,方法所以也能出来
    }
    
    
    
    
    //LinkedHashSet
    /*
     LinkedHashSet:使用链表维护了一个添加进集合中的顺序,导致我们遍历LinkedHashSet集合元素是
     是按照添加进去的顺序遍历的。
     
     LinkedHashSet插入性能略低于HashSet,但在迭代访问Set里的全部元素时有很好的性能
     */
    @Test
    public void testLinkedSet() {
        Set set = new LinkedHashSet();
        set.add(123);
        set.add(456);
        set.add(new String("AA"));
        set.add(new String("BB"));
        set.add("BB");
        set.add(null);
        
        Iterator iterator =  set.iterator();
                while(iterator.hasNext()){
                    System.out.println(iterator.next());
/*
123
456
AA
BB
null
*/
                }
        System.out.println(set.size());// 5
        System.out.println(set);//[123, 456, AA, BB, null]
    }
    
    
    
    
    
    //TreeSet
      /*
          1.向TreeSet中添加的元素必须是同一个类
          2.可以按照添加进集合中的元素的指定的顺序遍历,像String,包装类等默认按照从小到大顺序遍历
          3.当向TreeSet中添加自定义类的对象时   
                 有两种排序方法:①自然排序:要求自定义类实现java.lang.Comparable接口,
并重写其compareTo(Object obj)抽象方法 在此方法中,指明按照自定义的哪个属性进行排序的。 ②定制排序 5.想TreeSet中添加元素时,首先按照comparTo()进行比较,一旦返回 0 ,虽然仅是两个对象的此属性相同, 但是程序会认为这两个对象时相同的,进而后一个对象就不能添加进来 注意:compartTo()与hashCode以及equals()三者保持一致
*/ //TreeSet的自然排序 @Test public void testTreeSet1() { Set set = new TreeSet(); // set.add(new String("AA")); // set.add(new String("AA")); // set.add("BS"); // set.add("SS"); // set.add("CS"); set.add(new Person("CC", 21)); set.add(new Person("MM", 25)); set.add(new Person("GG", 23)); set.add(new Person("LL", 28)); set.add(new Person("LL", 24)); /*Iterator iterator = set.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); //AA BS CS SS }*/ for(Object str:set){ System.out.println(str); //AA BS CS SS } } //TreeSet的定制排序 @Test public void testTreeSet2(){ //1.创建一个实现Comparator接口的类对象 Comparator com = new Comparator() { //向TreeSet中添加Customer类的对象,在此compare()方法中,指明是按照Customer的哪个属性排序的 @Override public int compare(Object o1, Object o2) { if(o1 instanceof Customer && o2 instanceof Customer){ Customer c1 = (Customer)o1; Customer c2 = (Customer)o2; int i = c1.getId().compareTo(c2.getId()); if(i == 0){ return c1.getName().compareTo(c2.getName()); } return i; } return 0; } }; //2.将此对象作为形参传递给TreeSet的构造器中 TreeSet set = new TreeSet(com); //3.向TreeSet中添加Comparator接口中的compare方法涉及的类的对象。 set.add(new Customer("AA",1002)); set.add(new Customer("CC",1005)); set.add(new Customer("GG",1003)); set.add(new Customer("DD",1004)); set.add(new Customer("HH",1002)); for(Object str: set){ System.out.println(str); } } }

 

 

Person

package com.aff.coll;

public class Person implements Comparable {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

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

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((age == null) ? 0 : age.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (age == null) {
            if (other.age != null)
                return false;
        } else if (!age.equals(other.age))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    // 当向TreeSet中添加Person类的对象时,依据此方法,确定按照哪个属性排列
    @Override
    public int compareTo(Object o) {
        if (o instanceof Person) {
            Person p = (Person) o;
        //return this.name.compareTo(p.name);//this.name/  String 类型的已经重写过了CompareTo方法
        //return this.age.compareTo(p.age);//想从大到小 只需要前面加一个 " - "
            int  i = this.name.compareTo(p.name);
            if(i == 0){//名字相同再比较年龄
                return this.age.compareTo(p.age);
            }else{
                return i;
            }
        }
        return 0;//属性一样的,添加不进去
    }
}

 

Customer

package com.aff.coll;

public class Customer {
    private String name;
    private Integer id;

    public Customer() {
        super();
    }

    public Customer(String name, Integer id) {
        super();
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Customer [name=" + name + ", id=" + id + "]";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Customer other = (Customer) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

}

 

以上是关于Set接口中的HashSet,LinkedHashSet,TreeSet的主要内容,如果未能解决你的问题,请参考以下文章

Java set接口之HashSet集合原理讲解

Java中的Set集合

Java——Link接口(ArrayList,LinkList)和Set接口(HashSet)

Java学习笔记5.3.1 Set接口 - HashSet类

Set接口

JAVA-基础(Set~HashSet)