Java集合之Set

interface Set

  • 无序、无下标、元素不能重复(当插入新元素时,会调用euqals进行比较)
  • 方法:全部继承自Collection中的方法
  • Set集合继承Collection接口,方法全部来自Collection接口,自身没有定义其他方法。
  • Set接口主要两个实现类为HashSet、TreeSet。
  • Set集合中的元素不按特定顺序排序。因此无法向list一样根据索引获取数据。
  • 引用到堆上同一个对象的两个引用是相等的。如果对两个引用调用hashCode方法,会得到相同的结果,如果对象所属的类没有覆盖Object的hashCode方法的话,hashCode会返回每个对象特有的序号(java是依据对象的内存地址计算出的此序号),所以两个不同的对象的hashCode值是不可能相等的。

Set下几个重要的实现类与接口

  • HashSet(类)
  • LinkedHashSet(类)
  • SortedSet(接口)下的TreeSet(class )
- Class HashSet【重点】:
  • 存取HashSet集合中的元素,是根据哈希码来存取。HashSet根据哈希码来确定元素在集合中存储的位置(内存地址)
  • HashSet不能保证迭代顺序,且允许元素为null
  • 比较两个HashSet集合是否相同,先比较hasCode()返回的值是否相同,在使用equals()方法比较两个HashSet存储位置是否相同。如果满足以上两个条件,则HashSet集合相同。
  • hasCode()和equals()方法必须一起使用,以保证判断HashSet一致性。
  • 无参构建初始容量16 和负载因子0.75
  • 线程不安全,存取速度快。底层是以hash表实现的。
public class TestHashSet{
	public static void main(String[] args){
		HashSet<String> hashset = new HashSet<String>();
		hashset.add("中国");
		hashset.add("美国");
		hashset.add("日本");
		hashset.add("英国");
		System.out.println(hashset.add("中国")); // 输出false 不重复
		//System.out.println(map);
		//清空HashSet中的所有元素
		//hashset.clear();
		System.out.println(hashset);
		//删除指定名称的元素
		hashset.remove("日本");
		System.out.println(hashset);
		//使用迭代器遍历HashSet中的所有元素
		Iterator iterator = hashset.iterator(); 
           while (iterator.hasNext()){
                 System.out.println("遍历HashSet中的所有元素: "+iterator.next());  
              }
        //获取HashSet集合中的元素个数
        hashset.size();
	}
}
  • HashSet如何去重
    1)HashSet底层使用的是HashMap类,即是使用
    ctrl+shift+o快速导入包
    哈希码不唯一,两个不同对象,巧合版的哈希码相同,HashSet怀疑两个对象对不对就是相同对象,调用
    当存入元素的哈希码相同时,会调用equals进行确定,如结果为true,则拒绝后者存入
    HashCode比较是否相同,如果相同,表示可能是重复对象,先调==再调equals
    euqals二次确认
LinkedHashSet:
  • 底层使用LinkedHashMap(链表结构)存储,按照链表进行存储,既可保留元素的插入顺序
  • LinkedHashSet 是 Set 的一个具体实现,其维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可为插入顺序或是访问顺序。
  • LinkedHashSet 继承与 HashSet,并且其内部是通过 LinkedHashMap 来实现的。有点类似于我们之前说的LinkedHashMap 其内部是基于 Hashmap 实现一样,不过还是有一点点区别的。
  • 如果需要迭代的顺序为插入顺序或者访问顺序,那么 首先考虑LinkedHashSet
  • 除了内部存储,可保留元素的插入顺序以外使用方法与HashSet没什么区别
Interface SortedSet
class TreeSet
  • 实现了SortedSet接口,要求必须可以对元素排序。
  • 所有插入元素,必须实现Comparab方法mpareTofangfa
  • 根据compareTo方法返回0作为去重的依据,(意味重复)
  • TreeSet集合中的元素是有顺序的,如果要排序直接使用TreeSet
  • TreeSet的使用和其他集合差不多
  • 红-黑树的数据结构,默认对元素进行自然排序(String)。如果在比较的时候两个对象返回值为0,那么元素重复。
    红黑树算法的规则: 左小右大。
import java.util.TreeSet;
public class TestTreeSet {

    public static void main(String[] args) {

        TreeSet<String> tsb=new TreeSet();
        tsb.add("张三");
        tsb.add("李四");
        tsb.add("王五");
        tsb.add("赵六");
        tsb.add("黑七");
        System.out.println("树集合"+tsb);
        System.out.println("树集合的第一个元素"+tsb.first());
        System.out.println("树集合最后一个 元素"+tsb.last());
        System.out.println("头(李四)"+tsb.headSet("李四"));
        System.out.println("尾(李四)"+tsb.tailSet("李四"));
        System.out.println("ceiling(四)"+tsb.ceiling("四"));
        // 遍历迭代
        Iterator<String> iterator = tsb.iterator();
          while (iterator.hasNext()){
             System.out.println(iterator.next());
          }
       }
}

既然TreeSet可以自然排序,那么TreeSet必定是有排序规则的。

1:让存入的元素自定义比较规则。

2:给TreeSet指定排序规则。

方式一:元素自身具备比较性

元素自身具备比较性,需要元素实现Comparable接口,重写compareTo方法,也就是让元素自身具备比较性,这种方式叫做元素的自然排序也叫做默认排序。

方式二:容器具备比较性

当元素自身不具备比较性,或者自身具备的比较性不是所需要的。那么此时可以让容器自身具备。需要定义一个类实现接口Comparator,重写compare方法,并将该接口的子类实例对象作为参数传递给TreeMap集合的构造方法。

注意:当Comparable比较方式和Comparator比较方式同时存在时,以Comparator的比较方式为主;

注意:在重写compareTo或者compare方法时,必须要明确比较的主要条件相等时要比较次要条件。(假设姓名和年龄一直的人为相同的人,如果想要对人按照年龄的大小来排序,如果年龄相同的人,需要如何处理?不能直接return 0,因为可能姓名不同(年龄相同姓名不同的人是不同的人)。此时就需要进行次要条件判断(需要判断姓名),只有姓名和年龄同时相等的才可以返回0.)

通过return 0来判断唯一性。

因为字符串实现了一个接口,叫做Comparable 接口,所以字符串默认输出是按升序排列字符串重写了该接口的compareTo 方法,所以String对象具备了比较性.那么同样道理,我的自定义元素(例如Person类,Book类)想要存入TreeSet集合,就需要实现该接口,也就是要让自定义对象具备比较性.

存入TreeSet集合中的元素要具备比较性.

比较性要实现Comparable接口,重写该接口的compareTo方法

TreeSet属于Set集合,该集合的元素是不能重复的,TreeSet如何保证元素的唯一性

通过compareTo或者compare方法中的来保证元素的唯一性。

添加的元素必须要实现Comparable接口。当compareTo()函数返回值为0时,说明两个对象相等,此时该对象不会添加进来。

比较器接口

----| Comparable
compareTo(Object o) 元素自身具备比较性
----| Comparator
compare( Object o1, Object o2 ) 给容器传入比较器

TreeSet集合排序的两种方式:
一、让元素自身具备比较性。
也就是元素需要实现Comparable接口,覆盖compareTo 方法。
这种方式也作为元素的自然排序,也可称为默认排序。
二、让容器自身具备比较性,自定义比较器。

  • 定义一个类实现Comparator 接口,覆盖compare方法。
  • 并将该接口的子类对象作为参数传递给TreeSet集合的构造函数。
  • 当Comparable比较方式,及Comparator比较方式同时存在,以Comparator比较方式为主。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值