Java集合-----Set详解

    Set是没有重复元素的集合,是无序的

   1.HashSet

      HashSet它是线程不安全的

      HashSet常用方法:

  •   add(E element)  将指定的元素添加到此集合(如果尚未存在) 
  •   size()  返回此集合中的元素数(其基数) 
package com.gather;
/**
 * 人实体类
 * @author yyx 
 * 2019年2月27日
 */
public class Person {
    private String userName;
    private Integer userAge;

    public Person(String userName, Integer userAge) {
        super();
        this.userName = userName;
        this.userAge = userAge;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public Integer getUserAge() {
        return userAge;
    }

    public void setUserAge(Integer userAge) {
        this.userAge = userAge;
    }

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

}
package com.gather;

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

/**
 * HashSet底层实现是HashMap
 * 
 * @author yyx 2019年2月25日
 */
public class HashSetPractise {
    public static void main(String[] args) {
        Set<Person> hPersons = new HashSet<>();
        Person p1 = new Person("张三", 22);
        Person p2 = new Person("李四", 23);
        hPersons.add(p1);
        hPersons.add(p2);
        //第一种遍历方式
        for(Person person:hPersons) {
            System.out.println(person);
        }
        System.out.println("----------------");
        //第二种遍历方式
        Iterator<Person> it = hPersons.iterator();
        while (it.hasNext()) {
            Person person = it.next();
            System.out.println(person.toString());
        }
    }
}

   2.TreeSet

      TreeSet它是线程不安全的

  • 向TreeSet中添加的元素必须是同一个类的
  • 可以按照添加进集合中的元素的指定的顺序遍历。像String,包装类等默认按照从小到大的顺序遍历
  • 当向TreeSet中添加自定义类的对象时,有两种排序方法:①自然排序②定制排序
  • 自然排序:要求自定义类实现java.lang.Comparable接口并重写其compareTo(Object obj)的抽象方法在此方法中,指明按照自定义类的哪个属性进行排序
  • 向TreeSet中添加元素时,首先按照compareTo()进行比较,一旦返回0,虽然仅是两个对象的此属性值相同,但是程序会认为这两个对象是相同的,进而后一个对象就不能添加进来
package com.gather;

/**
 * 用户实体类
 * 
 * @author yyx 2019年2月26日
 */
public class User {
    private String userName;
    private Integer userAge;

    public User(String userName, Integer userAge) {
        super();
        this.userName = userName;
        this.userAge = userAge;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public Integer getUserAge() {
        return userAge;
    }

    public void setUserAge(Integer userAge) {
        this.userAge = userAge;
    }

    @Override
    public String toString() {
        return "User [userName=" + userName + ", userAge=" + userAge + "]";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((userAge == null) ? 0 : userAge.hashCode());
        result = prime * result + ((userName == null) ? 0 : userName.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;
        User other = (User) obj;
        if (userAge == null) {
            if (other.userAge != null)
                return false;
        } else if (!userAge.equals(other.userAge))
            return false;
        if (userName == null) {
            if (other.userName != null)
                return false;
        } else if (!userName.equals(other.userName))
            return false;
        return true;
    }
}
package com.gather;

import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class TreeSetPractise {
    public static void main(String[] args) {
        // 创建一个实现了Comparator接口的类对象
        Comparator<Object> com = new Comparator<Object>() {
            // 向TreeSet中添加Customer类的对象,在此compare()方法中,指明是按照Customer
            // 的哪个属性排序的。
            @Override
            public int compare(Object o1, Object o2) {
                if (o1 instanceof User && o2 instanceof User) {
                    User c1 = (User) o1;
                    User c2 = (User) o2;
                    int i = c1.getUserAge().compareTo(c2.getUserAge());
                    if (i == 0) {
                        return c1.getUserName().compareTo(c2.getUserName());
                    }
                    return i;
                }
                return 0;
            }
        };

        Set<User> rSet = new TreeSet<User>(com);

        rSet.add(new User("CC", 23));
        rSet.add(new User("MM", 21));
        rSet.add(new User("GG", 25));
        rSet.add(new User("JJ", 24));

        /*
         * 当Person类没有实现Comparable接口时,当向TreeSet中添加User对象后, 遍历报ClassCastException
         */
        Iterator<User> it = rSet.iterator();
        while (it.hasNext()) {
            User User = it.next();
            System.out.println(User.toString());
        }
    }
}

     注意:compareTo()与hashCode()以及equals()三者保持一致!

   3.LinkedHashSet

     LinkedHashSet 是 HashSet 的子类,其插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能

     LinkedHashSet 它是线程不安全的

package com.gather;

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * LinkedHashSet 是 HashSet 的子类
 * 
 * @author yyx 2019年2月25日
 */
public class LinkedHashSetPractise {
    public static void main(String[] args) {
        Set<Person> hUsers = new LinkedHashSet<>();
        Person p1 = new Person("AA", 22);
        Person p2 = new Person("GG", 32);
        hUsers.add(p1);
        hUsers.add(p2);
        Iterator<Person> it = hUsers.iterator();
        while (it.hasNext()) {
            Person person = it.next();
            System.out.println(person);
        }
    }
}