当前位置:   article > 正文

Java常用类库之集合Set_java set库

java set库

Set集合

与List类似,都是继承自Collection接口

与List不同,Set集合是不包含重复元素的集合。 更正式地说,集合不包含元素对e1和e2 ,使得e1.equals(e2)和最多一个null元素

注意:如果将可变对象用作set元素,则必须非常小心。比如存入Person()对象,有些Set集合中不同的属性会因为数据结构的不同运算出不同的位置,如果属性变化那么位置就不对,导致问题发生。

Set方法与List集合的方法类似,但是没有取数据的操作(get()),需要使用toArray()方法或iterator()读取数据。

1. HashSet

HashSet是Set接口下的常用类,散列存放(HashMap)

  • 不能输入重复元素
HashSet<String> set = new HashSet<>();
set.add("楚汉");
boolean flag1 = set.add("相争");
set.add("刘邦");
set.add("项羽");
boolean flag2 = set.add("相争");
System.out.println(flag1);
System.out.println(flag2);
//true
//false
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 使用迭代的方法遍历读取
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()){
    System.out.println(iterator.next());
}
//forEach方法比iterator更方便
for (String s: set) {
    System.out.println(s);
}
// 楚汉
// 刘邦
// 项羽
// 相争
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2. TreeSet

采用有序的二叉树存储,内部也是基于TreeMap,方法与HashSet类似

迭代器的快速失败和安全失败:

  • 迭代器迭代时数据被修改,导致遍历的结果是错误的,这就叫失败
  • 快速失败,集合改变,集合长度与迭代器遍历之前认为的长度不同,抛出异常
  • 安全失败:迭代前把集合复制了一份,迭代器迭代的是备份,修改的是原集合,不会出错
  • 有些集合是快速失败,有些集合是安全失败,不特殊描述一般是安全失败

TreeSet的iterator方法返回的迭代器是快速失败的 :如果在创建迭代器之后的任何时间修改集合,除了通过迭代器自己的remove方法之外,迭代器将抛出ConcurrentModificationException 。 因此,在并发修改的情况下,迭代器快速而干净地失败,而不是在未来的未确定时间冒任意,非确定性行为的风险。

TreeSet<String> data = new TreeSet<>();
data.add("B");
data.add("A");
data.add("F");
data.add("E");
for (String s:data) {
    System.out.println(s);
}
// A
// B
// E
// F
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

由上面可见,TreeSet根据字符的Unicode大小进行排序,但是如果遇到对象,含有多个可更改的属性,TreeSet如何排序

TreeSet<Person> data = new TreeSet<>();
Person p1 = new Person("李四", 18);
Person p2 = new Person("张三", 20);

data.add(p1);
data.add(p2);

for (Person  p:
        data) {
    System.out.println(p);
}

static class Person{
    private String name;
    private int age;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

抛出异常:ClassCastException: class Demo7$Person cannot be cast to class java.lang.Comparable
java.lang.Comparable 接口是用来实现比较大小的,这表明Person类的对象无法比较大小。

解决方法:

  1. Person()类继承Comparable接口,比较对象为Person。
  2. 重写compareTo方法自定义比较的规则
  3. compareTo返回值可以是:负数(this < o),0(this = o),正数(this > o)
static class Person implements Comparable<Person>{
    private String name;
    private int age;

    @Override
    public int compareTo(Person o) {
        //this与o比较
        //返回的可以是:负数(this<o),0(this=o),正数(this>o)
        return this.age-o.age;
    }
}
//输出:
//Person{name='李四', age=18}
// Person{name='张三', age=20}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

但是,此时如果加入年纪相同的对象Person p3 = new Person("王五", 18),由于Set集合不会存储相同数据,而通过compareTo发现18岁的人已经存在,所以不会存入。

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

闽ICP备14008679号