一、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()); }
总结: