一、HashSet
此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。
代码:
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
class Person
{
String name;
int id;
public Person(String name, int id) {
this.name = name;
this.id = id;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
}
public class Main2 {
public static void main(String[] args) {
Set<String> set1=new HashSet<>();
Set<Person> set2=new HashSet<>();
set1.add("abc");
set1.add("def");
set1.add("aaa");
set1.add("xzz");
set1.add("xyz");
Person p1=new Person("zhangsan",1);
Person p2=new Person("lisi",3);
Person p3=new Person("zhaoyiming",2);
set2.add(p1);
set2.add(p2);
set2.add(p3);
for(String i:set1)
{
System.out.print(i+" ");
}
System.out.println();
for (Person person:set2)
{
System.out.print(person+" ");
}
}
}
运行结果:
虽然看似其输出结果是有序的,一些时候可以认为进行默认规则排序:字母和数字从小到大,字符串或中文随机存储。但不能认为其有序。
- 无序性:HashSet 是无序的,即不会记录插入的顺序。
常见问题 1(ConcurrentModificationException)
HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。
常见异常代码:
(可自行将其中的HashSet改为LinkedHashSet和TreeSet,运行)
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
public class Main1 {
public static void main(String[] args) {
Set<String> set1=new HashSet<>();
set1.add("howAreU");
set1.add("Fine");
set1.add("thankU");
set1.add("andYou");
set1.add("ok");
for(String s:set1)
{
if(s.equals("Fine"))
set1.remove(s);
}
//set1.removeIf(s -> s.equals("Fine"));//可以用这句替换
}
}
运行结果:
常见问题2:自定义排序
HashSet实际上是一个 HashMap 实例,不支持自定义排序,可以认为其只关心元素是否唯一,不关心其顺序。无论是实现Comparator还是Comparable都不会影响其中元素的顺序。
( 排序->Treeset )
二、LinkedHashSet
按照插入顺序排序,且不受重新插入的元素影响。即相当于只算第一次插入。
是HashSet的子类,同HashSet一样,不是线程安全,也不支持自定义排序。
题目中要求按照输入顺序输出时,基本上可以用。
三、TreeSet
默认规则排序(字母和数字)从小到大。如果其中元素是对象,则按照第一个属性排序
不是线程安全,支持自定义排序。
自定义排序演示代码:
import java.util.*;
class Person implements Comparable
{
String name;
int id;
public Person(String name, int id) {
this.name = name;
this.id = id;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
@Override
public int compareTo(Object o) { //定义排序标准,这里按照id从小到大
Person p=(Person) o;
return this.id-p.id;
}
}
public class Main2 {
public static void main(String[] args) {
Set<Person> set2=new TreeSet<>();
Person p1=new Person("zhangsan",1);
Person p2=new Person("lisi",3);
Person p3=new Person("zhaoyiming",2);
set2.add(p1);
set2.add(p2);
set2.add(p3);
for (Person person:set2)
{
System.out.println(person+" ");
}
}
}
运行结果 :
我对Java接触不深,仍有太多太多要学,如有错误欢迎指出,感谢。