赞
踩
与List类似,都是继承自Collection接口
与List不同,Set集合是不包含重复元素的集合。 更正式地说,集合不包含元素对e1和e2 ,使得e1.equals(e2)和最多一个null元素。
注意:如果将可变对象用作set元素,则必须非常小心。比如存入Person()对象,有些Set集合中不同的属性会因为数据结构的不同运算出不同的位置,如果属性变化那么位置就不对,导致问题发生。
Set方法与List集合的方法类似,但是没有取数据的操作(get()),需要使用toArray()方法或iterator()读取数据。
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
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
//forEach方法比iterator更方便
for (String s: set) {
System.out.println(s);
}
// 楚汉
// 刘邦
// 项羽
// 相争
采用有序的二叉树存储,内部也是基于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
由上面可见,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; }
抛出异常:ClassCastException: class Demo7$Person cannot be cast to class java.lang.Comparable
java.lang.Comparable 接口是用来实现比较大小的,这表明Person类的对象无法比较大小。
解决方法:
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}
但是,此时如果加入年纪相同的对象Person p3 = new Person("王五", 18)
,由于Set集合不会存储相同数据,而通过compareTo发现18岁的人已经存在,所以不会存入。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。