Day17
集合
Set集合的概述及特点
A: Set集合的概述及特点
* 查看API
B: 案例演示
public static void demo1 ( ) {
HashSet< String> hs = new HashSet < > ( ) ;
boolean b1 = hs. add ( "a" ) ;
boolean b2 = hs. add ( "a" ) ;
hs. add ( "b" ) ;
hs. add ( "c" ) ;
hs. add ( "d" ) ;
System. out. println ( hs) ;
System. out. println ( b1) ;
System. out. println ( b2) ;
for ( String string : hs) {
System. out. println ( string) ;
}
}
HashSet存储自定义对象保证元素唯一性
案例演示
* 1. 创建Person类;
* 2. 单独重写equals ( ) 方法无用, 不能删除重复
* 3. 再重写HashCode, 重写的equals会被执行
HashSet如何保证元素唯一性的原理
A:HashSet原理
*我们使用set集合都是需要去除重复元素的,如果存储的时候逐个equals()方法比较,效率较低,哈希算法提高了去重复的效率,降低了使用equals()方法的频率;
*当HashSet调用add()方法存储对象的时候,先调用对象的hashCode方法得到一个哈希值,然后在集合中查找是否有哈希值相同的对象;
*如果没有哈希值相同的对象,就直接存入集合;
*如果有哈希值相同的对象,就和哈希值相同的对象逐个进行equals()比较,比较结果为true不存,比较结果为false就存入;
B:将自定义的对象存入HashSet去重复
*类中必须重写hashCode()方法和equals()方法;
*hashCode():属性相同的对象返回值必须相同,属性不同的返回值尽量不同(提高效率);
*equals():属性相同返回true,属性不同返回false,返回false存储
LinkedHashSet的概述和使用
LinkedHashSet的特点: 可以保证怎么存就怎么取
* LinkedHashSet
* 底层是链表实现的, 是set集合中唯一一个能保证怎么存就怎么取的集合对象
* 因为是HashSet的子类, 所以也是保证元素唯一的, 与HashSet的原理一样
集合使用演练
分析:
public static void main ( String[ ] args) {
Random r = new Random ( ) ;
HashSet< Integer> hs = new HashSet < > ( ) ;
while ( hs. size ( ) < 10 ) {
hs. add ( r. nextInt ( 20 ) + 1 ) ;
}
for ( Integer integer : hs) {
System. out. println ( integer) ;
}
}
public static void main ( String[ ] args) {
Scanner sc = new Scanner ( System. in) ;
System. out. println ( "请输入一行字符串:" ) ;
LinkedHashSet< Character> hs = new LinkedHashSet < > ( ) ;
String line = sc. nextLine ( ) ;
char [ ] arr = line. toCharArray ( ) ;
for ( char c : arr) {
hs. add ( c) ;
}
for ( Character ch : hs) {
System. out. print ( ch) ;
}
}
public static void main ( String[ ] args) {
ArrayList< String> list = new ArrayList < > ( ) ;
list. add ( "a" ) ;
list. add ( "a" ) ;
list. add ( "a" ) ;
list. add ( "b" ) ;
list. add ( "b" ) ;
list. add ( "b" ) ;
list. add ( "c" ) ;
list. add ( "c" ) ;
list. add ( "c" ) ;
list. add ( "c" ) ;
getSingle ( list) ;
System. out. println ( list) ;
}
public static void getSingle ( List< String> list) {
LinkedHashSet< String> lhs = new LinkedHashSet < > ( ) ;
lhs. addAll ( list) ;
list. clear ( ) ;
list. addAll ( lhs) ;
}
}
TreeSet集合的概述和使用
* TreeSet集合是用来对象元素进行排序的, 同样他也可以保证元素的唯一
* 底层是二叉树, 小的存储在左子树上( compareTo方法返回负值) ; 大的存储在左子树上( compareTo方法返回正值) , 然后中序遍历读出
public static void demo1 ( ) {
TreeSet< Integer> ts = new TreeSet < > ( ) ;
ts. add ( 3 ) ;
ts. add ( 1 ) ;
ts. add ( 1 ) ;
ts. add ( 2 ) ;
ts. add ( 2 ) ;
ts. add ( 3 ) ;
ts. add ( 3 ) ;
System. out. println ( ts) ;
* 当compareTo方法返回0 的时候集合中只有一个元素
* 当compareTo方法返回正数的时候集合会怎么存就怎么取
* 当compareTo方法返回负数的时候集合会倒序存储
@Override
public int compareTo ( Person o) {
int num = this . age - o. age;
return num == 0 ? this . name. compareTo ( o. name) : num;
}
案例演示
public static void demo3 ( ) {
TreeSet< Person> ts = new TreeSet < > ( ) ;
ts. add ( new Person ( "李四" , 13 ) ) ;
ts. add ( new Person ( "张三" , 23 ) ) ;
ts. add ( new Person ( "王五" , 43 ) ) ;
ts. add ( new Person ( "赵六" , 33 ) ) ;
System. out. println ( ts) ;
}
@Override
public int compareTo ( Person o) {
int num = this . name. compareTo ( o. name) ;
return num == 0 ? this . age - o. age : num;
}
@Override
public int compareTo ( Person o) {
int length = this . name. length ( ) - o. name. length ( ) ;
int num = length == 0 ? this . name. compareTo ( o. name) : length;
return num == 0 ? this . age - o. age : num;
}
TreeSet比较器(Comparator)排序
class CompareByLen implements Comparator < String> {
@Override
public int compare ( String s1, String s2) {
int num = s1. length ( ) - s2. length ( ) ;
return num == 0 ? s1. compareTo ( s2) : num;
}
TreeSet原理
1. 特点
* TreeSet是用来排序的, 可以指定一个顺序, 对象存入之后会按照指定的顺序排列
2. 使用排序
* a: 自然顺序
* TreeSet类的add ( ) 方法中会存入的对象提升为Comparable类型;
* 调用对象的comparaTo ( ) 方法和集合中的对象比较;
* 根据compareTo ( ) 方法返回的结果进行存储;
* 比较器顺序( Comparator)
* 创建TreeSet的时候可以定制一个Comparator
* 如果传入了Comparator的子类对象, 那么TreeSet就会按照比较器中的顺序排序
* add ( ) 方法内部会自动调用Comparator接口中的compare ( ) 方法排序
* 两种方式的区别
* TreeSet构造函数什么都不传, 默认按照类中的comparable的顺序( 没有就报错ClassCastException)
* TreeSet如果传入Comparator, 就先按照Comparator
案例演示
package com. heima. test;
import java. util. ArrayList;
import java. util. Comparator;
import java. util. List;
import java. util. TreeSet;
public class Test4 {
public static void main ( String[ ] args) {
ArrayList< String> list = new ArrayList < > ( ) ;
list. add ( "aaa" ) ;
list. add ( "aaa" ) ;
list. add ( "ccc" ) ;
list. add ( "ddd" ) ;
list. add ( "fffffffffff" ) ;
list. add ( "heima" ) ;
list. add ( "itcast" ) ;
list. add ( "bbbb" ) ;
list. add ( "aaa" ) ;
list. add ( "aaa" ) ;
sort ( list) ;
System. out. println ( list) ;
}
public static void sort ( List< String> list) {
TreeSet< String> ts = new TreeSet < > ( new Comparator < String> ( ) {
@Override
public int compare ( String s1, String s2) {
int num = s1. compareTo ( s2) ;
return num == 0 ? 1 : num;
}
} ) ;
ts. addAll ( list) ;
list. clear ( ) ;
list. addAll ( ts) ;
}
}
package com. heima. test;
import java. util. Comparator;
import java. util. Scanner;
import java. util. TreeSet;
public class Test5 {
public static void main ( String[ ] args) {
Scanner sc = new Scanner ( System. in) ;
System. out. println ( "请输入一个字符串" ) ;
String line = sc. nextLine ( ) ;
char [ ] arr = line. toCharArray ( ) ;
TreeSet< Character> ts = new TreeSet < > ( new Comparator < Character> ( ) {
@Override
public int compare ( Character c1, Character c2) {
int num = c1. compareTo ( c2) ;
return num == 0 ? 1 : num;
}
} ) ;
for ( char c : arr) {
ts. add ( c) ;
}
for ( Character c : ts) {
System. out. print ( c) ;
}
}
}
public static void main ( String[ ] args) {
Scanner sc = new Scanner ( System. in) ;
TreeSet< Integer> ts = new TreeSet < > ( new Comparator < Integer> ( ) {
@Override
public int compare ( Integer i1, Integer i2) {
int num = i2. compareTo ( i1) ;
return num == 0 ? 1 : num;
}
} ) ;
while ( true ) {
String line = sc. nextLine ( ) ;
if ( "quit" . equals ( line) ) {
break ;
}
Integer i = Integer. parseInt ( line) ;
ts. add ( i) ;
}
for ( Integer integer : ts) {
System. out. println ( integer) ;
}
}
package com. heiam. bean;
public class Student {
private String name;
private int chinese;
private int math;
private int english;
private int sum;
public Student ( ) {
super ( ) ;
}
public Student ( String name, int chinese, int math, int english) {
super ( ) ;
this . name = name;
this . chinese = chinese;
this . math = math;
this . english = english;
this . sum = this . chinese + this . english + this . math;
}
public int getSum ( ) {
return sum;
}
@Override
public String toString ( ) {
return name + "," + chinese + "," + math + "," + english + "," + sum;
}
}
package com. heima. test;
import java. util. Comparator;
import java. util. Scanner;
import java. util. TreeSet;
import com. heiam. bean. Student;
public class Test8 {
public static void main ( String[ ] args) {
Scanner sc = new Scanner ( System. in) ;
System. out. println ( "请输入学生成绩,格式是姓名,语文成绩,数学成绩,英语成绩" ) ;
TreeSet< Student> ts = new TreeSet < > ( new Comparator < Student> ( ) {
@Override
public int compare ( Student s1, Student s2) {
int num = s2. getSum ( ) - s1. getSum ( ) ;
return num == 0 ? 1 : num;
}
} ) ;
while ( ts. size ( ) < 5 ) {
String line = sc. nextLine ( ) ;
String[ ] arr = line. split ( "," ) ;
int chinese = Integer. parseInt ( arr[ 1 ] ) ;
int math = Integer. parseInt ( arr[ 2 ] ) ;
int eglish = Integer. parseInt ( arr[ 3 ] ) ;
ts. add ( new Student ( arr[ 0 ] , chinese, math, eglish) ) ;
}
System. out. println ( "排序后的学生信息" ) ;
for ( Student student : ts) {
System. out. println ( student) ;
}
}
}