集合(二)
Set
概述及特點:元素唯一,即一個不包含重複元素的 collection。更確切地講,
set 不包含滿足 e1. equals ( e2) 的元素對 e1 和 e2,並且最多包含一個 null 元素。
一、HashSet
1、概述及特點
概述及特點:HashSet 底層數據結構是哈希表,線程不安全,效率高,元素無序(存取順序
不一致),且唯一(元素不可重複),可以是 null。
哈希表:JDK1. 7 之前是數組+ 鏈表,JDK1. 8 之後爲數組+ 鏈表+ 二叉樹
2、HashSet元素唯一性解析及代碼優化
代碼優化
import java. util. HashSet;
import java. util. Objects;
public class Blog1 {
public static void main ( String[ ] args) {
HashSet< Student> hashSet = new HashSet < > ( ) ;
hashSet. add ( new Student ( "張三" , 23 ) ) ;
hashSet. add ( new Student ( "李四" , 27 ) ) ;
hashSet. add ( new Student ( "王五" , 26 ) ) ;
hashSet. add ( new Student ( "張三" , 23 ) ) ;
hashSet. add ( new Student ( "李四" , 27 ) ) ;
hashSet. add ( new Student ( "王五" , 26 ) ) ;
hashSet. add ( new Student ( "趙六" , 25 ) ) ;
hashSet. add ( new Student ( "張三" , 24 ) ) ;
hashSet. add ( new Student ( "曾七" , 23 ) ) ;
System. out. println ( hashSet) ;
}
}
class Student {
String name;
int age;
public Student ( ) {
}
public Student ( String name, int age) {
this . name = name;
this . age = age;
}
@Override
public String toString ( ) {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}' ;
}
static int count= 1 ;
@Override
public boolean equals ( Object o) {
System. out. println ( "equals()方法執行了" + ( count++ ) + "次" ) ;
if ( this == o) return true ;
if ( o == null || getClass ( ) != o. getClass ( ) ) return false ;
Student student = ( Student) o;
return age == student. age &&
Objects. equals ( name, student. name) ;
}
@Override
public int hashCode ( ) {
return Objects. hash ( name, age) ;
}
}
運行結果:
equals ( ) 方法執行了1 次
equals ( ) 方法執行了2 次
equals ( ) 方法執行了3 次
[ Student{ name= '張三' , age= 23 } , Student{ name= '李四' , age= 27 } , Student{ name= '王五' , age= 26 } , Student{ name= '趙六' , age= 25 } , Student{ name= '張三' , age= 24 } , Student{ name= '曾七' , age= 23 } ]
Process finished with exit code 0
二、LinkedHashSet
概述及特點:LinkedHashSet 底層數據結構是鏈表和哈希表,元素有序且唯一,
鏈表保證了有序,哈希表保證了唯一,線程不安全,效率高
三、TreeSet
1、概述及特點
概述及特點:TreeSet 底層數據結構是二叉樹,元素唯一,且可以對元素進行排序,
排序:自然排序,比較器排序
二叉樹存儲數據保證元素唯一性且排序原理圖解
2、自然排序
自然排序:如果TreeSet()採用的是空參構造,那麼採用的就是自然排序,自然排序要求元素必須
實現一個Comparable接口,並實現這個接口中的一個compareTo比較方法,根據此方法的返回值的
正(右邊) 、負(左邊) 0(兩元素相同,不再向集合添加) 來決定元素排列的位置。
演示
import java. util. TreeSet;
public class Blog2 {
public static void main ( String[ ] args) {
TreeSet< Student> treeSet = new TreeSet < > ( ) ;
treeSet. add ( new Student ( "張三" , 23 ) ) ;
treeSet. add ( new Student ( "李四" , 27 ) ) ;
treeSet. add ( new Student ( "王五" , 26 ) ) ;
treeSet. add ( new Student ( "張三" , 23 ) ) ;
treeSet. add ( new Student ( "李四" , 27 ) ) ;
treeSet. add ( new Student ( "王五" , 26 ) ) ;
treeSet. add ( new Student ( "趙六" , 25 ) ) ;
treeSet. add ( new Student ( "張三" , 24 ) ) ;
treeSet. add ( new Student ( "曾七" , 23 ) ) ;
System. out. println ( treeSet) ;
}
}
class Student implements Comparable < Student> {
private String name;
private int age;
public Student ( ) {
}
public Student ( String name, int age) {
this . name = name;
this . age = age;
}
public int getAge ( ) {
return age;
}
public void setAge ( int age) {
this . age = age;
}
public String getName ( ) {
return name;
}
public void setName ( String name) {
this . name = name;
}
@Override
public String toString ( ) {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}' ;
}
@Override
public int compareTo ( Student o) {
int num= this . age- o. age;
int num1= num== 0 ? this . name. compareTo ( o. name) : num;
return num1;
}
}
運行結果:
[ Student{ name= '張三' , age= 23 } , Student{ name= '曾七' , age= 23 } , Student{ name= '張三' , age= 24 } , Student{ name= '趙六' , age= 25 } , Student{ name= '王五' , age= 26 } , Student{ name= '李四' , age= 27 } ]
Process finished with exit code 0
3、比較器排序
比較器排序:採用有參構造,在創建TreeSet對象時,需要傳入一個Comparetor 比較器
Comparator< T> 比較器:
int compare ( T o1, T o2) ;
演示
import java. util. Comparator;
import java. util. TreeSet;
public class Blog3 {
public static void main ( String[ ] args) {
TreeSet< Student> treeSet = new TreeSet < > ( new Comparator < Student> ( ) {
@Override
public int compare ( Student o1, Student o2) {
int num= o1. getAge ( ) - o2. getAge ( ) ;
int num1= num== 0 ? o1. getName ( ) . compareTo ( o2. getName ( ) ) : num;
return num1;
}
} ) ;
treeSet. add ( new Student ( "張三" , 23 ) ) ;
treeSet. add ( new Student ( "李四" , 27 ) ) ;
treeSet. add ( new Student ( "王五" , 26 ) ) ;
treeSet. add ( new Student ( "張三" , 23 ) ) ;
treeSet. add ( new Student ( "李四" , 27 ) ) ;
treeSet. add ( new Student ( "王五" , 26 ) ) ;
treeSet. add ( new Student ( "趙六" , 25 ) ) ;
treeSet. add ( new Student ( "張三" , 24 ) ) ;
treeSet. add ( new Student ( "曾七" , 23 ) ) ;
System. out. println ( treeSet) ;
}
}
class Student {
private String name;
private int age;
public Student ( ) {
}
public Student ( String name, int age) {
this . name = name;
this . age = age;
}
public int getAge ( ) {
return age;
}
public void setAge ( int age) {
this . age = age;
}
public String getName ( ) {
return name;
}
public void setName ( String name) {
this . name = name;
}
@Override
public String toString ( ) {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}' ;
}
}
運行結果:
[ Student{ name= '張三' , age= 23 } , Student{ name= '曾七' , age= 23 } , Student{ name= '張三' , age= 24 } , Student{ name= '趙六' , age= 25 } , Student{ name= '王五' , age= 26 } , Student{ name= '李四' , age= 27 } ]
Process finished with exit code 0
4、例題
import java. util. Random;
import java. util. TreeSet;
public class Blog4 {
public static void main ( String[ ] args) {
int number= 10 ;
Random random = new Random ( ) ;
TreeSet< Integer> treeSet = new TreeSet < > ( ) ;
for ( int i = 0 ; i < number; i++ ) {
boolean flag= treeSet. add ( random. nextInt ( 20 ) + 1 ) ;
if ( ! flag) {
i-- ;
}
}
System. out. println ( treeSet) ;
}
}
運行結果:
[ 1 , 5 , 6 , 7 , 10 , 11 , 12 , 14 , 15 , 17 ]
Process finished with exit code 0
四、Collections工具類
A: Collections類概述: 針對集合操作的工具類
B: Collections常用成員方法
public static < T> void sort ( List< T> list) : 排序, 默認按照自然順序
public static < T> int binarySearch ( List< ? > list, T key) : 二分查找
public static < T> T max ( Collection< ? > coll) : 獲取最大值
public static void reverse ( List< ? > list) : 反轉集合元素
public static void shuffle ( List< ? > list) : 隨機打亂元素