当前位置:   article > 正文

java set集合_怎么在java里建set

怎么在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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
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);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

五,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));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
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接口
  • 1
  • 2
  • 3

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();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

六,总结:

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

LinkedHashSet 了解:

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/996533
推荐阅读
相关标签
  

闽ICP备14008679号