目录
1.TreeSet
1.1概述
set特点 : 无序 不可重复,添加顺序和取出顺序不一定一致
TreeSet : 存进去的元素,会按照某个规则进行排序
数字 : 从小到大
字符串: 每一位的ASCII
日期 : 自然日期
1.2使用方式
public class Collection_01_Set {
public static void main(String[] args) {
//数字 升序排序
Set set = new TreeSet ();
set.add(10);
set.add(5);
set.add(2);
//重复的添加不进去
set.add(2);
//会报错,因为不是相同类型比较的时候会出现问题提示java.lang.Integer cannot be cast to java.lang.String
// set.add("mmm");
//[2, 5, 10]
System.out.println(set);
for (Object obj : set){
System.out.println(obj);
}
//字符串, 比较ASCII
Set sets = new TreeSet();
sets.add("1");
sets.add("12");
sets.add("123");
sets.add("2");
sets.add("23");
sets.add("3");
//[1, 12, 123, 2, 23, 3]
System.out.println(sets);
}
}
2. 排序
2.1 Comparable
TreeSet为什么可以排序 ?
因为添加的元素实现了Comparable接口
在向TreeSet中添加数据的时候,会自动调用该对象的ComparaTo()方法
所有 存储自定义类型的时候,如果要使用TreeSet那么必须实现Comparable接口
public class Collection_02_Comparable {
public static void main(String[] args) {
User u1 = new User(18);
User u2 = new User(20);
User u3 = new User(24);
User u4 = new User(22);
TreeSet set = new TreeSet();
set.add(u1);
set.add(u2);
set.add(u3);
set.add(u4);
System.out.println(set);
//ArrayList底层是数组,下标从0开始 默认初始化容量为10,
//扩大容量为原始容量的1.5倍
ArrayList users = new ArrayList();
users.add(u1);
users.add(u2);
users.add(u3);
users.add(u4);
//排序
Collections.sort(users);
//会自动调用comparable中的comparTo方法
System.out.println(users);
}
}
class User implements Comparable {
private int age ;
@Override
public int compareTo(Object o) {
//this是要添加的元素
//o是集中的元素
if(o instanceof User){
User user = (User) o;
//如果该方法返回 0 说明相等,不再添加
//如果该方法返回 小于 0 说明要添加的元素比集合中的元素小,就放前面
//如果该方法返回 大于0 说明要添加的元素比集合中的元素大, 就放后面
return this.age-user.age;
}
return 0;
}
@Override
public String toString() {
return "User [age=" + age + "]";
}
public User(int age) {
super();
this.age = age;
}
}
因为添加的时候 会自动调用Comparable中的compareTo方法,需要实现类实现
2.2Comparator
比较器两种方式 :
1. 要添加的元素实现Comparable接口并覆写comparaTO方法
2. 集合比较器 : Comparator比较器,元素自身不需要实现该接口
如果添加的元素不是我们自定义的类
1. 假如该类有排序,但是不是我们想要的结果,比如Integer,默认升序 , 但是我们想要降序,可以使用Comparato
2. 假如该类没有排序,没有实现Comparable,那么我们想要排序还是要使用Comparator因为类不是我们写的,所以我们无法更改人家的源码
如果添加的元素是我们写的,那么想要排序 使用Comparable,这样如果不能满足其他用户的排序规则,别人也可以使用Comparator进行更改
当comparable和comparator同时存在,那么comparator的优先级大于comparable
public class Collection_03_Comparator {
public static void main(String[] args) {
TreeSet set = new TreeSet(new Comparator(){
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
// 0 说明重复,不添加
// 大于0 往后放
// 小于0 往前放
return i2 - i1;
}
});
set.add(1);
set.add(3);
set.add(6);
set.add(2);
System.out.println(set);
}
}
2.3 Collecttions
package Collection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* List 想要排序,元素必须实现Comparable接口
* 如果没有实现,需要用Comparator
*
* @author 人间失格
* @data 2021年10月23日下午8:59:34
*/
public class Collection_04_Collections {
public static void main(String[] args) {
List list = new ArrayList();
list.add(1);
list.add(21);
list.add(2);
list.add(4);
list.add(15);
//因为Integer实现了Comparable接口,所以可以进行排序,默认升序
Collections.sort(list);
System.out.println(list);
//假如Integer没有实现Comparable 或者我们想要降序排序,那么 Integer就无法满足我们的要求
//需要使用Comparator解决
Collections.sort(list, new Comparator(){
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer) o1;
Integer i2 = ( Integer) o2;
//降序
return i2-i1;
}
});
//[21, 15, 4, 2, 1]
System.out.println(list);
}
}
2.4练习题
package Collection;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
public class Collection_05 {
public static void main(String[] args) {
//需求 : 按照字符串中的数值大小进行排序,而不是按照ASCII
//字符串 比较ASCII
Set strs =new TreeSet(new Comparator(){
@Override
public int compare(Object o1, Object o2) {
// 1 Object 转换为String
String s1 = (String)o1;
String s2 = (String) o2;
//2. 把String转换为int
int i1 = Integer.parseInt(s1);
int i2 = Integer.parseInt(s2);
//3. 比较 升序
return i1-i2;
}
});
strs.add("123");
strs.add("12");
strs.add("1");
strs.add("2");
strs.add("21");
strs.add("3");
System.out.println(strs);
}
}
3.范型
3.1概述
范型 : 类型检查,在编译是检查类型是否匹配
集合中 什么元素都能保存, 太杂 , 优点 : 可以保存任意类型的数据 缺点 : 操作起来必须先强制性类型转换才可以 , 否则会因为发生多态,造成无法访问子类的他又属性
引入范型之后 ,那么集合中就只能保存指定类型 , 优点 : 操作起来简单 缺点 : 只能保存指定的类型
而结合实际操作, 我们绝大部分都是用来保存统一类型的数据的
范型 只能写引用数据类型 (类 接口 数组) 不可以写基本数据类型
3.2使用
在源码中使用E表示了泛型
使用大写字母表示 : A,B,C,D,E,F,G......X,Y,Z都可以只不过是一个占位符而已
但是还是要合理选择
? 表示不确定的类型
T(Type) : 表示是一个具体的Java类型'
E( Element) : 表示是元素的类型(集合中保存的元素)
K , V
如果说规定了泛型 ,但是没有传入泛型,那么默认是Object
3.3自定义泛型
package Collection;
/**
* 自定义类型
*
* Type
*
* @author 人间失格
* @data 2021年10月24日下午6:17:48
*/
public class Collection_07_Geneic_02 {
public static void main(String[] args) {
Test t = new Test();
//规定范型之后只能存储规定的类型
// t.m1(123);
t.m1("xxx");
t.m1("xxx");
t.m1("xxx");
t.m1("xxx");
t.m1("xxx");
Test<String> t1 = new Test<String>();
Test<Integer> t2 = new Test<Integer>();
// t1.m1(1);
t1.m1("xxx");
t2.m1(1);
// t2.m1("xx");
System.out.println(t);
}
}
class Test<T>{
public void m1( T e){
String s = (String) e;
}
}