一、HashSet的总结
(一)
- HashSet是Set接口的实现,元素无序、不可重复,==底层是一个HashMap==,用以保存数据。
- 不能保证元素的排列顺序,顺序有可能发生变化。
- 线程不安全。
- 集合元素可以是null,但只存在一个null。
- 线程安全: ==HashSet是线程不安全的==,需要用 Collections.synchronizedSet() 对其进行包装。
案例一
@Test
public void HashSetTest1() {
HashSet<String> set = new HashSet<>();
set.add("照子龙");
set.add("官域");
set.add("草草");
set.add("流被");
set.add("流被2");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
String next = iterator.next();
if(next=="流被"){
iterator.remove();
}
System.out.println("结果:"+next);
}
System.out.println("大小:"+set.size());
}
案例三 线程不安全
@Test
public void HashSetTest2() throws InterruptedException {
HashSet<String> set = new HashSet<>();
//线程T-1
new Thread(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
for (int i = 1; i <=500; i++) {
set.add("a"+i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T-1").start();
//线程T-2
new Thread(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
for (int i = 495; i <= 1000; i++) {
set.add("a"+i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T-2").start();
Thread.sleep(1000);
System.out.println("大小:" + set.size());
}
案例三: 线程安全
@Test
public void HashSetTest2() throws InterruptedException {
// HashSet<String> set = new HashSet<>();
Set<String> set = Collections.synchronizedSet(new HashSet<>());
//线程T-1
new Thread(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
for (int i = 1; i <=500; i++) {
set.add("a"+i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T-1").start();
//线程T-2
new Thread(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
for (int i = 495; i <= 1000; i++) {
set.add("a"+i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T-2").start();
Thread.sleep(1000);
System.out.println("大小:" + set.size());
}
二、LinkedHashSet
- 是Set接口的实现,==继承于HashSet==,元素不可重复,==底层是一个LinkedMap==,用以保存数据。
- **==可保证元素的插入顺序。==**
是线程不安全的,需要用 Collections.synchronizedSet() 对其进行包装。
与HashSet的区别
LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet。即**==顺序访问性能好,插入、删除性能差。==**
案例一
@Test
public void LinkedHashSet() {
LinkedHashSet<String> set = new LinkedHashSet<>();
set.add("照子龙");
set.add("官域");
set.add("草草");
set.add("流被");
set.add("流被2");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
String next = iterator.next();
if(next=="流被"){
iterator.remove();
}
System.out.println("结果:"+next);
}
System.out.println("大小:"+set.size());
}
案例二
@Test
public void LinkSetTest1() throws InterruptedException {
LinkedHashSet<String> set = new LinkedHashSet<>();
//线程T-1
new Thread(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
for (int i = 1; i <=500; i++) {
set.add("a"+i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T-1").start();
//线程T-2
new Thread(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
for (int i = 495; i <= 1000; i++) {
set.add("a"+i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T-2").start();
Thread.sleep(1000);
System.out.println("大小:" + set.size());
}
线程安全
@Test
public void LinkSetTest1() throws InterruptedException {
//LinkedHashSet<String> set = new LinkedHashSet<>();
Set<String> set = Collections.synchronizedSet(new LinkedHashSet<>());
//线程T-1
new Thread(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
for (int i = 1; i <=500; i++) {
set.add("a"+i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T-1").start();
//线程T-2
new Thread(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
for (int i = 495; i <= 1000; i++) {
set.add("a"+i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T-2").start();
Thread.sleep(1000);
System.out.println("大小:" + set.size());
}
三、TreeSet
- TreeSet是SortedSet接口的唯一实现类,元素不可重复。==底层是一个TreeMap==,用以保存数据。
- TreeSet**==默认可保证元素的自然顺序(元素需要实现Comparable接口),可指定排序规则(需要重写元素的hashCode()方法和equals()方法)==**。
==TreeSet是线程不安全的==,需要用 Collections.synchronizedSet() 对其进行包装。
TreeSet的性能比HashSet差但是我们在需要排序的时候可以用TreeSet因为他是自然排序也就是升序下面是TreeSet实现代码这个类也似只能通过迭代器迭代元素
案例一
@Test
public void TreeSet() {
TreeSet<String> set = new TreeSet<>();
set.add("照子龙");
set.add("官域");
set.add("草草");
set.add("流被");
set.add("流被2");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
String next = iterator.next();
if(next=="流被"){
iterator.remove();
}
System.out.println("结果:"+next);
}
System.out.println("大小:"+set.size());
}
案例二
@Test
public void TreeSet2() {
TreeSet<String> set = new TreeSet<>();
set.add("G");
set.add("B");
set.add("C");
set.add("A");
set.add("D");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
String next = iterator.next();
System.out.println("结果:"+next);
}
System.out.println("大小:"+set.size());
}
案例三
@Test
public void TreeSet1() throws InterruptedException {
TreeSet<String> set = new TreeSet<>();
//线程T-1
new Thread(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
for (int i = 1; i < 500; i++) {
set.add("a"+i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T-1").start();
//线程T-2
new Thread(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
for (int i = 498; i <= 1000; i++) {
set.add("a"+i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T-2").start();
//线程T-3
/* new Thread(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
String next = iterator.next();
if("a5".equals(next)){
iterator.remove();
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T-3").start();*/
Thread.sleep(1000);
System.out.println("大小:" + set.size());
}
案例四 线程安全
@Test
public void TreeSet1() throws InterruptedException {
// TreeSet<String> set = new TreeSet<>();
// ConcurrentSkipListSet<String> set = new ConcurrentSkipListSet<>();
Set<String> set = Collections.synchronizedSet(new TreeSet<>());
//线程T-1
new Thread(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
for (int i = 1; i < 500; i++) {
set.add("a"+i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T-1").start();
//线程T-2
new Thread(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
for (int i = 498; i <= 1000; i++) {
set.add("a"+i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T-2").start();
//线程T-3
/* new Thread(() -> {
System.out.println("当前线程:" + Thread.currentThread().getName());
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
String next = iterator.next();
if("a5".equals(next)){
iterator.remove();
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T-3").start();*/
Thread.sleep(1000);
System.out.println("大小:" + set.size());
}
总结: