java set集合

一,set:

是Collection的子接口,一个不包含重复元素的集合,set集合提供的方法与父接口Collection的方法完全一致,即没有关于下标的操作方法

set接口有两个常用的子实现类HashSet,TreeSet

二,HashSet:

HashSet实现了Set接口,底层是hash表(实际上底层是HashMap),该类不允许重复元素,不保证迭代顺序,即无序,(插入顺序和遍历顺序不一致)。

1,构造方法:

HashSet()
构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。
HashSet(Collection<? extends E> c)
构造一个包含指定 collection 中的元素的新 set。
HashSet(int initialCapacity)
构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和默认的加载因子(0.75)。
HashSet(int initialCapacity, float loadFactor)
构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和指定的加载因子。

2,方法:

HashSet类中的方法与父接口Set接口中的方法一致,即又跟Collection接口中的方法一致,所有的都能用

boolean add(E e)
如果此 set 中尚未包含指定元素,则添加指定元素。
boolean remove(Object o)
如果指定元素存在于此 set 中,则将其移除。
int size()
返回此 set 中的元素的数量(set 的容量)。

        HashSet<Object> hashSet = new HashSet<>();
        //空参
        //System.out.println(hashSet);
//        hashSet.add(1);
//        hashSet.add(2);
//        hashSet.add(3);
//        hashSet.add(1);
//        hashSet.add("..");
//        hashSet.add("邓");
//        hashSet.add("森");
//        hashSet.add("洋");
        //重复元素去除,无序输出
        //System.out.println(hashSet);
        //迭代遍历
//        Iterator<Object> iterator = hashSet.iterator();
//        while (iterator.hasNext()){
//            Object next = iterator.next();
//            System.out.print(next+" ");
//        }
        //foreach遍历
//        for (Object o: hashSet
//             ) {
//            System.out.print(o+" ");
//        }
        //移除元素
//        boolean remove = hashSet.remove("..");
//        System.out.println(remove);
        //返回集合容量
//        int size = hashSet.size();
//        System.out.println(size);
        //构造方法HashSet(Collection o),去除ArrayList集合中的重复元素
//        ArrayList<Object> list = new ArrayList<>();
//        list.add(1);
//        list.add(1);
//        list.add(2);
//        list.add(2);
//        list.add(3);
//        list.add(3);
//        list.add(4);
//        list.add(4);
//        HashSet<Object> hashSet1 = new HashSet<>(list);
//        System.out.println(hashSet1);
        //判断是否为空
        //System.out.println(hashSet.isEmpty());
        //判断是否包含指定元素
//        boolean contains = hashSet.contains(1);
//        System.out.println(contains);
        //判断是否包含所有元素
//        boolean b = hashSet.containsAll(hashSet);
//        System.out.println(b);
        //将指定集合放到hashset集合中,去除重复
//        boolean b = hashSet.addAll(list);
//        System.out.println(b);
//        System.out.println(hashSet);
        //清空集合
//        hashSet.clear();
//        System.out.println(hashSet);
        //移除集合HashSet中的ArrayList集合的元素
//        boolean b = hashSet.removeAll(list);
//        System.out.println(b);
//        System.out.println(hashSet);
3,扩容:

HashSet底层是Hash表,其实是HashMap,初始容量16,加载因子 0.75,扩容的阈值 = 容量 * 0.75 ,超过阈值就触发扩容,扩容2倍,初始容量和加载因子可以通过构造方法创建时修改的。

4,去重原理:

1,调用add(E,e)方法时,会在底层调用元素e的hashcode方法来获得对象的地址值

2,如果地址值不一样,直接存储

3,如果地址值一样,会再调用元素的equals方法判断内容是否一样

4,如果equals不一样,那么就存储,如果equals判断为true,那么去重

三,LinkedHashSet:

LinkedHashSet既有HashSet的去重又有Linked结构有序的特性,即存储在LinkedHashSet中的元素既有不允许重复,又能保证迭代顺序

 LinkedHashSet<Integer> integers = new LinkedHashSet<>();
        //既有序,又去重
        integers.add(111);
        integers.add(222);
        integers.add(333);
        integers.add(12);
        integers.add(222);
        System.out.println(integers);
    }

五,TreeSet:

TreeSet是基于基于TreeMap的NavigableSet实现,可以使用元素的自然顺序对元素进行排序或者根据创建的set时提供的Comparator进行排序,具体取决于使用的构造方法,即TreeSet会对存储的元素排序,当然也会去重

1,演示方法:

构造方法:

TreeSet()
构造一个新的空set,set根据其元素的自然顺序进行排序。
TreeSet(Comparator<? super E> comparator)
构造一个新的空TreeSet,它根据指定比较器进行排序。

方法:

有常规的集合的方法,还有一些基于数据结构能排序的特性才有的特殊方法,取值范围的(ceiling(),floor(),lower(),higher(),),首尾取值的(first(),last())

TreeSet<Integer> treeSet= new TreeSet<>();
        //去重(不能存储重复元素)并排序(升序)
        treeSet.add(3);
        treeSet.add(2);
        treeSet.add(4);
        treeSet.add(1);
        treeSet.add(3);
        //System.out.println(treeSet);
        for (Integer integer : treeSet) {
            //System.out.println(integer);
        }
        //获得排序后的第一个
        //System.out.println(treeSet.first());
        //获得排序后的最后一个
        //System.out.println(treeSet.last());
        //System.out.println(treeSet);
        //获取并移除排序后的第一个
        //System.out.println(treeSet.pollFirst());
        //获取并移除排序后的最后一个
        //System.out.println(treeSet.pollLast());
        //集合中已经不存在拿出的元素
        //System.out.println(treeSet);
        //返回此set中严格小于给定元素的最大元素
        System.out.println(treeSet.lower(100));
2,去重原理:

前提知识: TreeSet底层是TreeMap,TreeMap是红黑树,是一种平衡二叉树(AVL)

练习1:新建User类(age,name),创建TreeSet集合,创建多个User对象,将user对象存入TreeSet集合,实现去重排序,1) 年龄和姓名一致则去重 2) 按照年龄从小到大排序

 TreeSet<User> set = new TreeSet<>( );
  set.add(new User(18,"厄加特"));
  // 运行报错ClassCastException 无法转成Comparable接口

Comparable接口,强行对实现它的每个类的对象进行整体排序,这种排序被称为类的自然排序.
实现这个接口,需要重写comparTo方法,该方法返回值决定了是升序,降序还是去重!

该comparTo(T t)方法运行时 , this指代当前正在调用该方法的对象,参数T就是之前已经存在的元素.

  • 返回值 0 ,意味着此元素(正在存储的元素)和之前的元素相同,即不存储,则去重
  • 返回值正整数,意味着此元素 大于之前的元素, 放在该节点的右边
  • 返回值负整数,意味着此元素小于之前的元素,放在该节点的左边

最后都存储完毕时,取值时采用中序遍历(从根节点开始按照左,中,右的顺序读取)

public class User implements Comparable<User>{
// 属性和方法...
    
/**
 * this 是指代正在存储的元素
 * o    是之前存储的元素
 */
@Override
public int compareTo(User o) {
    System.out.println("此对象--> " + this);
    System.out.println("指定对象--> " + o);
    // 姓名和年龄相同返回0,即去重不存储
    if (this.name.equals(o.getName()) && this.getAge() - o.getAge() == 0) {
        return 0;
    }
    // 年龄相同返回1,即保留下来的不去重的意思
    // 年龄不同的话就正常相减,返回负数或正数
    return this.getAge() - o.getAge() == 0 ? 1 : this.getAge() - o.getAge();
}

六,总结:

HashSet方法与父接口Collection中的方法一致,直接用,面试题:HashSet底层(HashMap),扩容,去重原理

LinkedHashSet 了解:

TreeSet底层树结构了解就行,只需要知道要想去重排序,必须要实现接口重写方法,返回0去重,返回负放左子树,返回正放右子树

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值