学习目标:
小白起飞第18天
学习内容:
treeSet添加的元素必须排序
两种方式 :
1 要添加的元素对应的类实现java.lang.Comparable接口,并实现compareTo方法
2 使用java.util.Comparator比较器类
如果要添加的元素,符合两种比较器(都有) 则 Comparator优先(compare方法)
Comparable : 要添加的元素,实现该接口并覆写compareTo方法
Comparator : 比较器类,常应用 : 比如Integer默认升序,我想降序怎么办? 使用Comparator进行降序排序
如果 添加的元素的类 是我们写的,我们应该使用 Comparable , 因为对扩展开发,其他人还可以使用 Comparator 实现新的排序功能
如果 添加的元素的类 不是我们写的
1 该类有排序(实现了Comparable) 比如Integer,但是 默认排序结果不是我们想要的,那么我们可以使用Comparator进行调整排序,因为优先级高
2 如果该类没有实现排序(没有实现Comparable), 这时候我们需要使用Comparator进行排序,因为我们不可能去改变人家类的源码
import java.util.Comparator;
import java.util.TreeSet;
public class _collection01 {
@SuppressWarnings(“unchecked”)
public static void main(String[] args) {
// TreeSet treeSet = new TreeSet(new SortTest());
TreeSet treeSet = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
return i2-i1;
}
});
treeSet.add(1);
treeSet.add(12);
treeSet.add(11);
treeSet.add(3);
treeSet.add(5);
for (Object object : treeSet) {
System.out.println(object);
}
}
}
class SortTest implements Comparator{
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
//降序
return i2-i1;
}
}
import java.util.Comparator;
import java.util.TreeSet;
public class _collection02 {
@SuppressWarnings(“unchecked”)
public static void main(String[] args) {
TreeSet treeSet = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Student s1 = (Student) o1;
Student s2 = (Student) o2;
if (s1.getId() < s2.getId()) {
//比较Id的大小
return -1;
}else if (s1.getId() > s2.getId()) {
return 1;
}else{
//当Id一样时,按照年龄升序
return s1.getAge() - s2.getAge();
}
}
});
treeSet.add(new Student(1, 19, "张三1"));
treeSet.add(new Student(2, 18, "张三2"));
treeSet.add(new Student(3, 16, "张三3"));
treeSet.add(new Student(3, 13, "张三4"));
treeSet.add(new Student(3, 18, "张三5"));
for (Object object : treeSet) {
System.out.println(object);
}
}
}
class Student{
private int id;
private int age ;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [id=" + id + ", age=" + age + ", name=" + name + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//全参构造
public Student(int id, int age, String name) {
super();
this.id = id;
this.age = age;
this.name = name;
}
import java.util.ArrayList;
import java.util.Collections;
//List想要实现排序,必须实现 Comparable接口
public class _collection03 {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add(2);
arrayList.add(22);
arrayList.add(12);
arrayList.add(5);
// 可以使用这个方法 是因为 Integer 中 实现了 Comparable接口
Collections.sort(arrayList);
//输出的是数组形式带有中括号
System.out.println(arrayList);
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
// 如果 自身 的Comparable实现的排序方式,不是我们想要的,或者 没有实现Comparable排序,需要使用comparator
public class _collection04 {
@SuppressWarnings(“unchecked”)
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add(2);
arrayList.add(22);
arrayList.add(12);
arrayList.add(5);
Collections.sort(arrayList,new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
//降序
return i2-i1;
}
});
System.out.println(arrayList);
}
}
import java.util.HashSet;
import java.util.Set;
public class _collection05 {
@SuppressWarnings(“unchecked”)
public static void main(String[] args) {
Set set = new HashSet();
set.add(new Employee(“1”, “张三1”));
set.add(new Employee(“2”, “张三”));
set.add(new Employee(“3”, “张三”));
set.add(new Employee(“1”, “张三2”));
/*
* hashCode执行了
*hashCode执行了
*hashCode执行了
*hashCode执行了
*equals执行了
*Employee [no=1, name=张三1]
*Employee [no=2, name=张三]
*Employee [no=3, name=张三]
*由输出结果知,有几个对象hashCode执行几次,当K有相同的情况下,执行equals,最后相同的结果用之前数据,而不是覆盖
*/
for (Object object : set) {
System.out.println(object);
}
}
}
class Employee {
private String no;
private String name;
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Employee(String no, String name) {
super();
this.no = no;
this.name = name;
}
@Override
public String toString() {
return "Employee [no=" + no + ", name=" + name + "]";
}
@Override
public int hashCode() {
System.out.println("hashCode执行了");
return no.hashCode();
}
@Override
public boolean equals(Object obj) {
System.out.println("equals执行了");
if (this == obj) {
return true;
}
if (obj instanceof Employee) {
Employee e = (Employee)obj;
if (no.equals(e.no)) {
return true;
}
}
return false;
}
}
public class _generic {
public static void main(String[] args) {
MyClass mc = new MyClass();
mc.m1(2);
// 默认是Object 想 传什么 就穿什么
mc.m1(“asd”);
MyClass<String> class1 = new MyClass<String>();
// 只能传递String
// class1.m1(213);
class1.m1("asdasd");
}
}
// T就相当于是个标签,占位符
// 就是这里需要客户端传递一个类型,用传递的类型替换这个T
// 如果不传,默认是Object
class MyClass {
public void m1(T t) {
System.out.println(t);
}
}
- 类型检查 : 编译过程中,检查数据类型是否匹配
- 什么是泛型 : 集合就跟数组一样,都是只能放同一种数据类型的
- 集合中存放任意类型是因为Object,元素都向上转型了,但是这样虽然能够存储任意类型,但是使用起来不方便
- 比如只要保存小数,如果我们还是要Object的话,那么取出数据之后一定要向下转型才能使用
- ,而引入泛型之后,我们可以指定存储的类型,那么编译器在编译阶段,就会检查添加的数据的类型是否匹配,不匹配就报错
- 泛型只能是引用数据类型,不能是基本数据类型
- 优点 : 统一了数据类型,减少数据类型转换
- 缺点 : 只能存储单一类型的元素
就是在集合声明的时候指定了该集合的数据类型,指明了类型之后,再向集合中添加数据的时候,编译器就会对数据类型进行校验
*/
public class _generic01 {
public static void main(String[] args) {
// 不使用泛型
Set s = new HashSet();
A a = new A();
B b = new B();
C c = new C();
s.add(a);
s.add(b);
s.add©;
// 使用的时候,就需要向下转型
for (Object object : s) {
if (object instanceof A) {
A a1 = (A) object;
a1.m1();
}else if (object instanceof B) {
B b1 = (B) object;
b1.m2();
}else if (object instanceof C) {
C c1 = (C) object;
c1.m3();
}
}
}
}
class A{
public void m1(){
System.out.println("—");
}
}
class B{
public void m2(){
System.out.println(“11111”);
}
}
class C{
public void m3(){
System.out.println("====");
}
}
***虽然指定了泛型,但是 存进去的元素 还是会发生向上转型为Object类型
只是 取出来的时候,可以直接获取元素类型,不需要强制类型转换
泛型常用的标记 T , ? , E , K , V
T type : 表示是一个java类型
E Element : 元素,表示集合或者数组中的数据
KV : key,value 键值对
? : 表示一个不确定的类型
如果规定了泛型,我们可以指定数据类型,如果不指定的情况下,默认是Objec***
public class _generic02 {
public static void main(String[] args) {
Set<String> strs = new HashSet<String>();
// 不能保存Integer
// strs.add(1);
strs.add("aa");
strs.add("bb");
strs.add("cc");
// 使用泛型的方式 都相同
// 虽然指定了泛型,但是 存进去的元素 还是会发生向上转型为Object类型
// 只是 取出来的时候,可以直接获取元素类型,不需要强制类型转换
List<Integer> list = new ArrayList<Integer>();
for (String string : strs) {
System.out.println(string);
}
}
}
public class _generic03 {
public static void main(String[] args) {
// map需要指定两个 KV
Map<String, Integer> xxx = new HashMap<String, Integer>();
}
Map : 无序 可重复
-
value可重复, key不可重复
-
Map和 集合的操作 基本都是一样的
-
Object put(Object key,Object value) : 向map中添加键值对
-
void clear() : 清空
-
int size() : 添加个数
-
boolean isEmpty() : 判断是否为空
-
Object get(Object key) : 根据key 获取value
-
Collection values() : 获取map中的所有value值,以集合形式返回
-
booelan containsKey(Object key) : 判断是否包含某个key
-
booelan containsValue(Object value) : 判断是否包含某个value
-
Set keySet() : 获取map中的所有key,以Set集合形式返回
-
Set entrySet() : 返回map中的键值对映射(key=value),以Set集合形式返回
-
V remove(Object key) : 根据key删除指定映射关系,返回value值
-
map不能直接遍历,可以通过keySet 等方法进行间接遍历
*/
public class _Map01 {
public static void main(String[] args) {
Map<Object, Object> map = new HashMap<Object, Object>();
map.put(“A”, “one”);
map.put(“B”, “two”);
map.put(“C”, “three”);
//此处key和value的形式不同也能被输入
map.put(1003, “rose”);
map.put(‘A’, 1000);
map.put(65, 1000);
map.put("‘A’", 1000);
System.out.println(map.get(“A”));
//此处key 的值和上边的值有重复,并且上边输出的是one,下边输出的是3000,所以one的值被覆盖了
map.put(“A”, 3000);
System.out.println(map.get(“A”));
// key和 value可以都是null,但是没什么意义,并且只能有一个key为null
map.put(null, null);
// 返回键值对的个数为8,而不是9,此处null键值对是被输入的,而形式不同的1003,“rose”没有被添加
System.out.println(map.size());
//此处为检测“1003”是否被添加进去
// 调用"1003"的hashCode值,然后进行hash 得到数组下标
// 用该对象调用equals方法,和数组中链表的所有对象的key进行比较
// 此对象为 字符串1003 而 map中 没有,只有一个Integer的1003
// false
System.out.println(map.containsKey(“1003”));
//map.put(“1003”, “rose”);
System.out.println(map.containsKey(“1003”));
System.out.println("-------");
// 只能去挨个遍历比较
// true
System.out.println(map.containsValue(“rose”));
// 先根据"C" 调用HashCode 然后进行hash,得到数组下标,挨个和链表中对象进行equals比较
// 找到对应的对象后,获取其value值
// three
System.out.println(map.get(“C”));System.out.println("========"); // 获取所有的value 并遍历 Collection<Object> c = map.values(); for (Object object : c) { System.out.println(object); } System.out.println("------------------"); // 根据key,删除指定键值对,并返回value值 // three System.out.println(map.remove("C")); System.out.println("------------------"); // 把map中所有的key取出,返回set Set keys = map.keySet(); for (Object key : keys) { System.out.println(key+" : "+map.get(key)); } System.out.println("===="); // 把键值对封装到entry中并以set形式返回 Set entrys = map.entrySet(); for (Object object : entrys) { // 转换为Entry类型 Entry entry = (Entry) object; System.out.println(entry.getKey()+" : "+entry.getValue()); }
}
特殊的Map : 强制规定键和值都必须是字符串
java.util.Properties
public class _Map02 {
public static void main(String[] args) {
Properties p = new Properties();
p.setProperty(“driver”, “xxx”);
p.setProperty(“username”, “root”);
//不是字符串报错
//p.setProperty(1003, “root”);
String driver = p.getProperty(“driver”);
System.out.println(driver);
// 可以传递两个参数,第二个参数是默认值,
// 如果根据password是这个key能够找到对应的value,就取对应的value
// 如果找不到,map中没有password这个key 那么 就返回 admin
System.out.println(p.getProperty("username","admin"));
//这里没有”1003'返回的是admin
System.out.println(p.getProperty("1003","admin"));
}
}
SortedMap是接口,子实现了是TreeMap,元素必须有序,会按照某个规定进行排序
*
- 实现排序的原因 :
-
1 被添加的元素,实现了Comparable接口
-
2 按照需求,编写一个比较器类,该比较器类必须实现Comparator接口
*/
public class _Map03 {
public static void main(String[] args) {
TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
// 因为Integer实现了Comparable接口,默认升序
map.put(1, 2);
map.put(12, 2);
map.put(13, 2);
map.put(5, 2);
Set key = map.keySet();
//默认升序
for (Object object : key) {
System.out.println(object +" : “+map.get(object));
}
System.out.println(”--------");
// 更改 为降序 使用Comparator编写匿名内部类
map = new TreeMap<Integer, Integer>(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
return i2-i1;
}
});
map.put(1, 2);
map.put(12, 2);
map.put(13, 2);
map.put(5, 2);
Set<Integer> keys = map.keySet();
for (Object object : keys) {
System.out.println(object +" : "+map.get(object));
}
}
}
使用Comparable实现
public class _Map04 {
@SuppressWarnings(“unchecked”)
public static void main(String[] args) {
SortedMap map = new TreeMap();
//此处为全参构造,输入商品,和商品对应的价格
Product p1 = new Product(“大白菜”, 3.5);
Product p2 = new Product(“大葱”, 8.0);
Product p3 = new Product(“土豆”, 2.2);
// key表示商品 value表示购买数量
map.put(p1, 3);
map.put(p2, 3);
map.put(p3, 1);
Set keys = map.keySet();
for (Object key : keys) {
int value = (Integer) map.get(key);
Product product = (Product) key;
String name = product.getName();
double price = product.getPrice();
System.out.println(name +":"+price+"元" +"每kg"+ " , 购买了 " + value+" kg , 共 : "+(price*value)+"元 ");
}
}
}
class Product implements Comparable {
private String name;
private double price;
@Override
public String toString() {
return "Product [name=" + name + ", price=" + price + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Product(String name, double price) {
super();
this.name = name;
this.price = price;
}
@Override
public int compareTo(Object o) {
Product p = (Product) o;
if (price > p.price) {
return 1;
}else if (price < p.price) {
return -1;
}else{
// treeMap是靠 compareTo方法决定是否唯一,而 get()方法 是根据key调用compareTo方法和每个key进行比较,返回0,说明相等,就获取value
return 0;
}
}
}
使用Comparable实现
public class _Map04 {
@SuppressWarnings(“unchecked”)
public static void main(String[] args) {
SortedMap map = new TreeMap();
//此处为全参构造,输入商品,和商品对应的价格
Product p1 = new Product(“大白菜”, 3.5);
Product p2 = new Product(“大葱”, 8.0);
Product p3 = new Product(“土豆”, 2.2);
// key表示商品 value表示购买数量
map.put(p1, 3);
map.put(p2, 3);
map.put(p3, 1);
Set keys = map.keySet();
for (Object key : keys) {
int value = (Integer) map.get(key);
Product product = (Product) key;
String name = product.getName();
double price = product.getPrice();
System.out.println(name +":"+price+"元" +"每kg"+ " , 购买了 " + value+" kg , 共 : "+(price*value)+"元 ");
}
}
}
class Product implements Comparable {
private String name;
private double price;
@Override
public String toString() {
return "Product [name=" + name + ", price=" + price + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Product(String name, double price) {
super();
this.name = name;
this.price = price;
}
@Override
public int compareTo(Object o) {
Product p = (Product) o;
if (price > p.price) {
return 1;
}else if (price < p.price) {
return -1;
}else{
// treeMap是靠 compareTo方法决定是否唯一,而 get()方法 是根据key调用compareTo方法和每个key进行比较,返回0,说明相等,就获取value
return 0;
}
}
}
学习时间:
提示:这里可以添加计划学习的时间
例如:
1、 周一至周五晚上 7 点—晚上9点
2、 周六上午 9 点-上午 11 点
3、 周日下午 3 点-下午 6 点
学习产出:
提示:这里统计学习计划的总量
例如:
1、 技术笔记 2 遍
2、CSDN 技术博客 3 篇
3、 学习的 vlog 视频 1 个