集合(二)
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) : 随机打乱元素