Java集合3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
开发工具与关键技术:
作者:陈剑波
撰写时间:2019年06月09日
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Set集合
set集合可以存储多个对象,但并不会记住元素的存储顺序,也不允许集合中有重复元素(不同的set集合有不同的判断方法)。
HashSet和TreeSet是Set的两个典型实现。
HashSet的性能总是比TreeSet好(特别是常用的添加、查询元素等操作),因 为TreeSet需要额外的红黑树算法来维护集合元素的次序。只有当需要一个保持排序的 Set时,才应该使用TreeSet,否则一般都应该使用HashSet。
HashSet还有一个子类:LinkedHashSet,对于普通的插入、删除操作, LinkedHashSet比HashSet要略微慢一点,这是由维护链表所带来的额外开销造成 的,但由于有了链表,遍历LinkedHashSet会更快。
一、HashSet类
HashSet类是Set接口的典型实现类,大多数时候使用Set集合时就是使用这个实 现类。 HashSet类按Hash算法来存储集合中的元素,因此具有很好的存取和查找性 能。
HashSet类具有以下特点:
- 不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。
- HashSet不是同步的(不是线程安全的),如果多个线程同时访问一个 HashSet,假设有两个或者两个以上线程同时修改了 HashSet集合时,则必须通 过代码来保证其同步。
- 集合元素值可以是null,但只能放入一个null。
当向 HashSet集合中存入一个元素时, HashSet会调用该对象的 hashCode()方法来得到该对象的hashCode值,然后根据该hashCode值决定该对 象在HashSet中的存储位置。如果有两个元素通过 equals方法比较返回true,但 它们的hashCode()方法返回值不相等, HashSet将会把它们存储在不同的位置,依然可以添加成功。
HashSet判断两个元素是否相等的依据是:两个对象的equals()比较返回false;且hashCode值不相等,判断两个元素不相等;两个对象通过equals()比较返回true,且HashCode()方法的返回值也相等;
示例代码:
import java.util.ArrayList; |
import java.util.HashSet; |
import java.util.Iterator; |
import java.util.List; |
import java.util.Set; |
|
/** |
* @author KO.ZERO |
*Set代表无序、不可重复的集合;HashSet是Set的实现类; |
*/ |
public class HashSetDemo { |
public static void main(String[] args) { |
HashSet<String> hashSet = new HashSet<>(); |
|
hashSet.add("F");//add(E e):如果set中尚未存在指定的元素,则添加此元素。 |
hashSet.add("A");//不允许添加重复元素 |
hashSet.add("A"); |
hashSet.add("S"); |
hashSet.add("D"); |
hashSet.add("G"); |
hashSet.add("T"); |
hashSet.add(null);//元素值可以是null,但只能放入一个null |
System.out.println(hashSet); |
// addAll(Collection c):如果set中没有指定collection中的所有元素,则将其添加到此set中。 |
List<String> list = new ArrayList<String>(); |
list.add("N"); |
list.add("M"); |
list.add("K"); |
hashSet.addAll(list); |
System.out.println(hashSet); |
// contains(Object o):如果set包含指定的元素,则返回true。 |
System.out.println(hashSet.contains("K")); |
// containsAll(Collection c):如果此set包含指定collection的所有元素,则返回 true。 |
System.out.println(hashSet.containsAll(list)); |
// equals(Object o):比较指定对象与此set的相等性。 |
System.out.println("N".equals("N")); |
// hashCode():返回set的哈希码值。 |
System.out.println("N".hashCode()); |
for (String string : list) { |
System.out.print(string + "的哈希码值=" + string.hashCode()+" "+"N".equals(string) + " "); |
} |
// isEmpty():如果set不包含元素,则返回 true。 |
System.out.println("\n"+"判断hashSet是否为空:"+hashSet.isEmpty()); |
// iterator():返回在此set中的元素上进行迭代的迭代器。 |
System.out.println("\nIterator迭代器:while"); |
Iterator<String> iterator = hashSet.iterator(); |
while (iterator.hasNext()) {//hasNext()方法判断容器中是否还有元素 |
String string = (String) iterator.next();//next()方法获取下一个元素 |
System.out.print(string + " "); |
} |
System.out.println("\nIterator迭代器:for"); |
for (Iterator<String> iterator2 = list.iterator(); iterator2.hasNext();) { |
String string = iterator2.next(); |
System.out.print(string + " "); |
} |
// size():返回set中的元素数(其容量)。 |
System.out.println("\n"+hashSet.size()); |
// remove(Object o):如果set中存在指定的元素,则将其移除。 |
System.out.println(hashSet); |
System.out.println(hashSet.remove("A")); |
System.out.println(hashSet); |
// removeAll(Collection c):移除set中那些包含在指定collection中的元素。 |
System.out.println("list="+list); |
System.out.println(hashSet.removeAll(list)); |
System.out.println(hashSet); |
// retainAll(Collection c):仅保留set中那些包含在指定collection中的元素。 |
List<String> list2 = new ArrayList<String>(); |
list2.add("D"); |
list2.add("T"); |
list2.add("F"); |
list2.add("G"); |
System.out.println(hashSet.retainAll(list2)); |
System.out.println(hashSet); |
} |
} |
运行结果:
[null, D, T, F, G, A, S] |
[null, D, T, F, G, A, S, M, N, K] |
true |
true |
true |
78 |
N的哈希码值=78 true M的哈希码值=77 false K的哈希码值=75 false |
判断hashSet是否为空:false |
Iterator迭代器:while |
null D T F G A S M N K |
Iterator迭代器:for |
N M K |
10 |
[null, D, T, F, G, A, S, M, N, K] |
true |
[null, D, T, F, G, S, M, N, K] |
list=[N, M, K] |
true |
[null, D, T, F, G, S] |
true |
[D, T, F, G] |
二、linkedHashSet类
LikedHashSet是HashSet的子类,LikedHashSet集合也是根据元素的HashCode值来决定元素的存储位置,但它能够同时使用链表来维护元素的添加次序,使得元素能以插入顺序保存。
LinkedHashSet需要维护元素的插入顺序,因此性能略低于 HashSet的性能,但 在迭代访问Set里的全部元素时将有很好的性能,因为它以链表来维护内部顺序。
示例代码:
import java.util.Iterator; |
import java.util.LinkedHashSet; |
|
/** |
* @author KO.ZERO |
*LinkedHashSet集合元素有序且唯一, |
*具有可预知的迭代顺序Set接口的哈希表和链接列表实现.线程不安全,效率高。 |
*/ |
public class LinkedHashSetDemo { |
public static void main(String[] args) { |
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>(); |
linkedHashSet.add("X"); |
linkedHashSet.add("T"); |
linkedHashSet.add("Q"); |
linkedHashSet.add("P"); |
linkedHashSet.add("B"); |
linkedHashSet.add("E"); |
linkedHashSet.add("U"); |
linkedHashSet.add(null); |
System.out.println(linkedHashSet); |
System.out.println("Iterator 迭代器:for"); |
for (Iterator<String> iterator = linkedHashSet.iterator(); iterator.hasNext();) { |
String string = iterator.next(); |
System.out.print(string + " "); |
} |
} |
} |
三、TreeSet类
TreeSet是 SortedSet接口的实现类, TreeSet可以确保集合元素处于排序状态(所谓排序状态,就是元素按照一定的规则排序,比如升序排列,降序排列)。与 Set集合相比,TreeSet还提供了如下几个额外的方法。
示例代码:
import java.util.Comparator; |
import java.util.Iterator; |
import java.util.Set; |
import java.util.SortedSet; |
import java.util.TreeSet; |
|
/** |
* @author KO.ZERO TreeSet集合:元素唯一,且能对元素进行排序线程不安全,效率高 |
*/ |
public class TreeSetDemo { |
public static void main(String[] args) { |
TreeSet<String> treeSet = new TreeSet<>(); |
// 添加元素 |
treeSet.add("G"); |
treeSet.add("J"); |
treeSet.add("Q"); |
treeSet.add("L"); |
treeSet.add("R"); |
treeSet.add("H"); |
treeSet.add("X"); |
treeSet.add("K"); |
treeSet.add("S"); |
// treeSet.add(null);//TreeSet集合不允许添加null值 |
System.out.println(treeSet); |
// first():返回此set中当前第一个(最低)元素。 |
System.out.println("第一个元素是:" + treeSet.first()); |
// last():返回此set中当前后一个(最高)元素。 |
System.out.println("最后一个元素是:" + treeSet.last()); |
// floor(E e):返回此set中小于等于给定元素的最大元素;如果不存 在这样的元素,则返回null。 |
System.out.println("treeSet集合中小于等于给定元素的最大元素:" + treeSet.floor("G")); |
// higher(E e):返回此set中严格大于给定元素的最小元素;如果不存 在这样的元素,则返回null。 |
System.out.println("treeSet集合中严格大于给定元素的最小元素:" + treeSet.higher("G")); |
// lower(E e):返回此 set 中严格小于给定元素的最大元素;如果不存在这样的元素,则返回null。 |
System.out.println("treeSet集合中严格小于给定元素的最大元素:" + treeSet.lower("G")); |
//ceiling(E e):返回此set中大于等于给定元素的最小元素;如果不存 在这样的元素,则返回null。 |
System.out.println("treeSet集合中大于等于给定元素的最小元素:" + treeSet.ceiling("G")); |
// headSet(E toElement):返回此set的部分视图,其元素严格小于toElement。 |
SortedSet<String> sortedSet1 = treeSet.headSet("K"); |
System.out.println(sortedSet1); |
// tailSet(E fromElement):返回此set的部分视图,其元素大于等于 fromElement。 |
SortedSet<String> sortedSet = treeSet.tailSet("K"); |
System.out.println(sortedSet); |
//subSet(E fromElement, E toElement):返回此set的部分视图,其元素从fromElement(包 |
// 括)到toElement(不包括)。 |
SortedSet<String> sortedSet2 = treeSet.subSet("L", "S"); |
System.out.println(sortedSet2); |
// 由于TreeSet是有序的,也支持Comparable和Comparator两种排序方式 |
System.out.println("TreeSet Comparable排序:"); |
Set<UniversityGradeComparable> universityGradeComparables = new TreeSet<UniversityGradeComparable>(); |
universityGradeComparables.add(new UniversityGradeComparable(1701, |
"DSSSF")); |
universityGradeComparables.add(new UniversityGradeComparable(1701, |
"ASRGR")); |
universityGradeComparables.add(new UniversityGradeComparable(1704, |
"ASG")); |
universityGradeComparables |
.add(new UniversityGradeComparable(1702, "HT")); |
universityGradeComparables.add(new UniversityGradeComparable(1704, |
"THN")); |
universityGradeComparables |
.add(new UniversityGradeComparable(1703, "TH")); |
universityGradeComparables |
.add(new UniversityGradeComparable(1703, "RH")); |
universityGradeComparables.add(new UniversityGradeComparable(1702, |
"RVB")); |
universityGradeComparables.add(new UniversityGradeComparable(1704, |
"IOHG")); |
universityGradeComparables.add(new UniversityGradeComparable(1703, |
"MJIUY")); |
// for循环使用迭代器遍历输出列表数据 |
for (Iterator<UniversityGradeComparable> iterator2 = universityGradeComparables |
.iterator(); iterator2.hasNext();) {// hasNext():判断是否有元素可以迭代,有则返回 // true。 |
// iterator():返回在此 collection 的元素上进行迭代的迭代器。 |
UniversityGradeComparable universityGradeComparable = iterator2 |
.next();// next():返回迭代的下一个元素。 |
System.out.print(universityGradeComparable.getClassAndGrade() + ":" |
+ universityGradeComparable.getStudentName() + "|"); |
} |
System.out.println("\nTreeSet Comparator排序:"); |
Set<UniversityGradeComparator> universityGradeComparators = new TreeSet<UniversityGradeComparator>( |
new Comparator<UniversityGradeComparator>() { |
@Override |
public int compare(UniversityGradeComparator o1, |
UniversityGradeComparator o2) { |
if (o1.getClassAndGrade() != o2.getClassAndGrade()) { |
return o1.getClassAndGrade() |
- o2.getClassAndGrade(); |
} else { |
return o2.getStudentName().compareTo( |
o1.getStudentName()); |
} |
} |
}); |
universityGradeComparators.add(new UniversityGradeComparator(1701, |
"向日葵")); |
universityGradeComparators.add(new UniversityGradeComparator(1704, |
"沙罗妲")); |
universityGradeComparators.add(new UniversityGradeComparator(1704, "巳月")); |
universityGradeComparators.add(new UniversityGradeComparator(1702, "鹿台")); |
universityGradeComparators.add(new UniversityGradeComparator(1701, "蝶蝶")); |
universityGradeComparators.add(new UniversityGradeComparator(1703, "佐井")); |
universityGradeComparators.add(new UniversityGradeComparator(1703, "鸣人")); |
universityGradeComparators.add(new UniversityGradeComparator(1702, "佐助")); |
universityGradeComparators.add(new UniversityGradeComparator(1704, "小樱")); |
universityGradeComparators.add(new UniversityGradeComparator(1703, "羽衣")); |
Iterator<UniversityGradeComparator> iterator = universityGradeComparators |
.iterator(); |
// iterator():返回在此 collection 的元素上进行迭代的迭代器。 |
while (iterator.hasNext()) {// hasNext():如果仍有元素可以迭代,则返回 true。 |
UniversityGradeComparator universityGradeComparator = (UniversityGradeComparator) iterator |
.next();// next():返回迭代的下一个元素。 |
System.out.print(universityGradeComparator.getClassAndGrade() + ":" |
+ universityGradeComparator.getStudentName() + "|"); |
} |
} |
} |
运行结果:
[G, H, J, K, L, Q, R, S, X] |
第一个元素是:G |
最后一个元素是:X |
treeSet集合中小于等于给定元素的最大元素:G |
treeSet集合中严格大于给定元素的最小元素:H |
treeSet集合中严格小于给定元素的最大元素:null |
treeSet集合中大于等于给定元素的最小元素:G |
[G, H, J] |
[K, L, Q, R, S, X] |
[L, Q, R] |
TreeSet Comparable排序示例代码: |
1701:ASRGR|1701:DSSSF|1702:HT|1702:RVB|1703:MJIUY|1703:RH|1703:TH|1704:ASG|1704:IOHG|1704:THN| |
TreeSet Comparator排序示例代码: |
1701:蝶蝶|1701:向日葵|1702:鹿台|1702:佐助|1703:鸣人|1703:羽衣|1703:佐井|1704:沙罗妲|1704:巳月|1704:小樱| |