1.1 排序
1.1.1 Comparable
比较器有两种 : 1 元素自身比较器, 2 比较器类
思考 : 为什么字符串,Integer,Date可以排序?
因为都实现了 implements Comparable
因为使用treeSet在进行数据添加的时候,会自动调用该对象的compareTo()方法和集合内元素进行比较
如果我们想要存储自定义类型怎么办?
需要实现该接口才行
添加的时候 会自动调用该对象的compareTo方法,而该方法就在Comparable接口中,所以 必须要实现,否则不能添加到TreeSet中
1.1.2 Comparator
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进行排序,因为我们不可能去改变人家类的源码
package com.demo._Collection;
import java.util.Comparator;
import java.util.TreeSet;
/**
* 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进行排序,因为我们不可能去改变人家类的源码
*
*/
public class Collection_10_Sort {
@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;//降序
}
}
package com.demo._Collection;
import java.util.Comparator;
import java.util.TreeSet;
public class Collection_11_Sort {
@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;
//先比较id,再比较年龄
if (s1.getId() < s2.getId()) {
return -1;
}else if (s1.getId() > s2.getId()) {
return 1;
}else{
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;
}
}
1.1.3 Collections
List排序,想要排序 元素必须实现 Comparable接口
package com.demo._Collection;
import java.util.ArrayList;
import java.util.Collections;
/**
* List排序,想要排序 元素必须实现 Comparable接口
*/
public class Collection_12_Sort {
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);
}
}
如果 自身 的Comparable实现的排序方式,不是我们想要的,或者 没有实现Comparable排序
package com.demo._Collection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/**
* 如果 自身 的Comparable实现的排序方式,不是我们想要的,或者 没有实现Comparable排序
*
* 那么我们应该如何对list排序呢?
*
* Comparator
*/
public class Collection_13_Sort {
@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() {//不能用自己的类去写,只能够重新定义一个排序类或者匿名内部类。
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
return i2-i1;//降序
}
});
System.out.println(arrayList);
}
}
1.1.4 总结
如果 添加的元素的类 是我们写的,我们应该使用 Comparable , 因为对扩展开发,其他人还可以使用 Comparator 实现新的排序功能
如果 添加的元素的类 不是我们写的
1 该类有排序(实现了Comparable) 比如Integer,但是 默认排序结果不是我们想要的,那么我们可以使用Comparator进行调整排序,因为优先级高
2 如果该类没有实现排序(没有实现Comparable), 这时候我们需要使用Comparator进行排序,因为我们不可能去改变人家类的源码
1.2 Set
1.2.1 TreeSet
TreeSet : 元素必须有序,添加的元素会按照某种规则自动排序
想要使用TreeSet,元素必须要排序
数字 : 默认从小到大
字符串 : 默认比较每位ASCII码
日期 : 默认比较自然日期 昨天-今天-明天
1.2.2 HashSet
1.2.2.1 散列表
hash算法 : 是一种安全的加密算法,把不定长的值改变为定长值,并不能保证唯一性
散列表 :
数组中 保存链表(单向链表),并且链表节点内有四个属性
1 key 2 value 3 next 4 hash
散列表是一种数据结构,不过java中屏蔽了,直接以封装的形式封装到了HashSet, HashMap 和HashTable中
其中hashTable已经过时
hash算法在java中 就是指 hashCode函数及重写
哈希的目的 就是为了查询快,因为hash是一个固定的值
1 hash过程
拿到对象,调用对象自身的hashCode()方法,然后进行hash算法,得到数组下标,把值保存到对应的数组中,
Set特性 : 无序 , 不可重复(hashCode和equals)
2 HashSet 和 HashMap
HashSet 就是HashMap的封装,本质就是一个HashMap
默认初始化容量 都是 16
封装之后 HashSet把value值屏蔽了,只能操作key,所以在使用set添加的时候,只需要传入key即可
3 添加过程
1 使用添加的键值对中的key,调用key的hashCode方法,生成hash值,进行hash算法得到数组下标
,判断该下标上是否有元素,如果没有,把该键值对 保存到该数组中即可
2 如果该数组中有对象,则调用key的equals方法和数组中的元素进行比较,如果相等则key不添加,value值覆盖
3 如果不相等,就把该 对象的 添加到已有元素的next属性,形成链表
4 如果添加的时候 就已经是链表了,则需要用key和链表中所有的元素key进行比较是否相等
1.2.2.2 HashSet 使用
因为散列表中 需要使用hashCode和equals来表示对象的唯一性
所以 在进行添加自定义类型的时候,需要考虑 按需求重新hashCode和equals方法
package com.demo._Collection;
import java.util.HashSet;
import java.util.Set;
/**
* hash算法 : 是一种安全的加密算法,把不定长的值改变为定长值,并不能保证唯一性
*
* 散列表 :
* 数组中 保存链表(单向链表),并且链表节点内有四个属性
* 1 key 2 value 3 next 4 hash
*
* 散列表是一种数据结构,不过java中屏蔽了,直接以封装的形式封装到了HashSet, HashMap 和HashTable中
* 其中hashTable已经过时
*
* hash算法在java中 就是指 hashCode函数及重写
*
* 哈希的目的 就是为了查询快,因为hash是一个固定的值
*
* 1 hash过程
* 拿到对象,调用对象自身的hashCode()方法,然后进行hash算法,得到数组下标,把值保存到对应的数组中,
*
* Set特性 : 无序 , 不可重复(hashCode和equals)
*
* 2 HashSet 和 HashMap
* HashSet 就是HashMap的封装,本质就是一个HashMap
* 默认初始化容量 都是 16
* 封装之后 HashSet把value值屏蔽了,只能操作key,所以在使用set添加的时候,只需要传入key即可
*
* 3 添加过程
* 1 使用添加的键值对中的key,调用key的hashCode方法,生成hash值,进行hash算法得到数组下标
* ,判断该下标上是否有元素,如果没有,把该键值对 保存到该数组中即可
* 2 如果该数组中有对象,则调用key的equals方法和数组中的元素进行比较,如果相等则key不添加,value值覆盖
* 3 如果不相等,就把该 对象的 添加到已有元素的next属性,形成链表
* 4 如果添加的时候 就已经是链表了,则需要用key和链表中所有的元素key进行比较是否相等
*
* 因为散列表中 需要使用hashCode和equals来表示对象的唯一性
* 所以 在进行添加自定义类型的时候,需要考虑 按需求重新hashCode和equals方法
*
*/
public class Collection_14_HashSet {
public static void main(String[] args) {
Set set = new HashSet();
set.add(2);
set.add(44);
set.add("xxx");
set.add("xxx");//只能够添加一种,唯一性
for (Object object : set) {
System.out.println(object);//打印出的顺序不一样,因为对添加的数据进行hash值算法,地址是不一样的
}
}
}
package com.demo._Collection;
import java.util.HashSet;
import java.util.Set;
public class Collection_15_HashSet {
@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”));
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;
}
}
2.1 概述
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 等方法进行间接遍历
Map用于保存具有映射关系的数据,因此Map集合里保存两组值。
2.2 常用方法
2.3 HashMap
package com.demo._Map;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* 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 Map_01 {
public static void main(String[] args) {
Map map = new HashMap();
//存储跟json一样{"A":"one","B":"two"}
map.put("A", "one");
map.put("B", "two");
map.put("C", "three");
map.put(1003, "rose");
map.put('A', 1000);
map.put(65, 1000);
map.put("'A'", 1000);
map.put("A", 3000);
// 支持 key和 value 都是null,但是没什么意义,并且只能有一个key为null
map.put(null, null);
// 8
System.out.println(map.size());
// 调用"1003"的hashCode值,然后进行hash 得到数组下标
// 用该对象调用equals方法,和数组中链表的所有对象的key进行比较
// 此对象为 字符串1003 而 map中 没有,只有一个Integer的1003
// false
System.out.println(map.containsKey("1003"));
// 只能去挨个遍历比较
// true
System.out.println(map.containsValue("rose"));
// 先根据"C" 调用HashCode 然后进行hash,得到数组下标,挨个和链表中对象进行equals比较
// 找到对应的对象后,获取其value值
// three
System.out.println(map.get("C"));
System.out.println("========");
// 获取所有的value 并遍历
Collection c = map.values();
for (Object object : c) {
System.out.println(object);
}
// 根据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());
}
}
}
2.4 扩展之Properties
特殊的Map : 强制规定键和值都必须是字符串
java.util.Properties
package com.demo._Map;
import java.util.Properties;
/**
* 特殊的Map : 强制规定键和值都必须是字符串
*
* java.util.Properties
*/
public class Map_02 {
public static void main(String[] args) {
Properties p = new Properties();
p.setProperty("driver", "xxx");
p.setProperty("username", "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"));
/** public String getProperty(String key, String defaultValue) {
String val = getProperty(key);
return (val == null) ? defaultValue : val;
}*/
}
}
2.5 SortedMap
SortedMap是接口,子实现了是TreeMap,元素必须有序,会按照某个规定进行排序
实现排序的原因 :
1 被添加的元素,实现了Comparable接口
2 按照需求,编写一个比较器类,该比较器类必须实现Comparator接口
package com.demo._Map;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeMap;
/**
* SortedMap是接口,子实现了是TreeMap,元素必须有序,会按照某个规定进行排序
*
* 实现排序的原因 :
* 1 被添加的元素,实现了Comparable接口
* 2 按照需求,编写一个比较器类,该比较器类必须实现Comparator接口
*/
public class Map_03_SortedMap {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
TreeMap map = new TreeMap();
// 因为Integer实现了Comparable接口,默认升序
// map.put(1, 2);
// map.put(12, 2);
// map.put(13, 2);
// map.put(5, 2);
// 更改 为降序 使用Comparator编写匿名内部类
map = new TreeMap(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 keys = map.keySet();
for (Object object : keys) {
System.out.println(object +" : "+map.get(object));
}
}
}
treeMap是靠 compareTo方法决定是否唯一,而 get()方法 是根据key调用compareTo方法和每个key进行比较,返回0,说明相等,就获取value
package com.demo._Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* 使用Comparable实现
*/
public class Map_04_SortedMap {
@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;
}
}
}
3. 泛型
3.1 概述
类型检查 : 编译过程中,检查数据类型是否匹配
什么是泛型 : 集合就跟数组一样,都是只能放同一种数据类型的,那么为什么集合中什么都能放呢?
Object , 元素都向上转型了,但是这样虽然能够存储任意类型,但是使用起来就不方便了
比如我现在要存储学生成绩,不要存储其他类型,只要保存小数即可,如果我们还是要Object的话,那么取出数据之后一定要向下转型才能使用
,而引入泛型之后,我们可以指定存储的类型,那么编译器在编译阶段,就会检查添加的数据的类型是否匹配,不匹配就报错
泛型只能是引用数据局类型,不能是基本数据类型
优点 : 统一了数据类型,减少数据类型转换
缺点 : 只能存储单一类型的元素
就是在集合声明的时候指定了该集合的数据类型,指明了类型之后,再向集合中添加数据的时候,编译器就会对数据类型进行校验
虽然指定了泛型,但是 存进去的元素 还是会发生向上转型为Object类型
只是 取出来的时候,可以直接获取元素类型,不需要强制类型转换
泛型常用的标记 T , ? , E , K , V
T type : 表示是一个java类型
E Element : 元素,表示集合或者数组中的数据
KV : key,value 键值对
? : 表示一个不确定的类型
如果 人家规定了泛型,可以让我们指定数据类型,如果我们不指定的情况下,默认是Object
3.2 使用
不使用泛型
什么也能放
但是获取使用的时候,需要向下 转型 比较麻烦
package com.demo._Generic;
import java.util.HashSet;
import java.util.Set;
/**
* 类型检查 : 编译过程中,检查数据类型是否匹配
*
* 什么是泛型 : 集合就跟数组一样,都是只能放同一种数据类型的,那么为什么集合中什么都能放呢?
* Object , 元素都向上转型了,但是这样虽然能够存储任意类型,但是使用起来就不方便了
*
* 比如我现在要存储学生成绩,不要存储其他类型,只要保存小数即可,如果我们还是要Object的话,那么取出数据之后一定要向下转型才能使用
* ,而引入泛型之后,我们可以指定存储的类型,那么编译器在编译阶段,就会检查添加的数据的类型是否匹配,不匹配就报错
*
* 泛型只能是引用数据局类型,不能是基本数据类型
*
* 优点 : 统一了数据类型,减少数据类型转换
* 缺点 : 只能存储单一类型的元素
*
就是在集合声明的时候指定了该集合的数据类型,指明了类型之后,再向集合中添加数据的时候,编译器就会对数据类型进行校验
*
*/
public class Generic_01 {
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(c);
// 使用的时候,就需要向下转型
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("====");
}
}
使用泛型之后
package com.demo._Generic;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 虽然指定了泛型,但是 存进去的元素 还是会发生向上转型为Object类型
*
* 只是 取出来的时候,可以直接获取元素类型,不需要强制类型转换
*
* 泛型常用的标记 T , ? , E , K , V
* T type : 表示是一个java类型
* E Element : 元素,表示集合或者数组中的数据
* KV : key,value 键值对
* ? : 表示一个不确定的类型
*
* 如果 人家规定了泛型,可以让我们指定数据类型,如果我们不指定的情况下,默认是Object
*
* @author 天亮教育-帅气多汁你泽哥
* @Date 2021年1月23日
*/
public class Generic_02 {
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);
}
}
}
虽然指定了泛型,但是 存进去的元素 还是会发生向上转型为Object类型
只是 取出来的时候,可以直接获取元素类型,不需要强制类型转换
3.3 自定义泛型
package com.demo._Generic;
public class Generic_04 {
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<T> {
public void m1(T t) {
System.out.println(t);
}
}
Map存储转换为List存储,并且要求使用value值进行排序
package com.demo._Map;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* Map转换为list 并以value进行排序
*/
public class Map_05 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 1);
map.put("b", 2);
map.put("c", 1);
map.put("d", 4);
map.put("e", 16);
// 1 map存储键值对 , 而List只能存储一个元素 (Entry)
// 2 map转换为Entry存储(entrySet)
Set<Entry<String, Integer>> entrySet = map.entrySet();
// 3 把set转换为List,泛型Entry
List<Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(
entrySet);
// System.out.println(list);
// 4 排序 , Comparator
Collections.sort(list, new Comparator<Entry<String, Integer>>() {
@Override
public int compare(Entry<String, Integer> o1,
Entry<String, Integer> o2) {
return o1.getValue() - o2.getValue();
}
});
// 打印
for (Entry<String, Integer> entry : list) {
System.out.println(entry);
}
}
}
文章浏览阅读90次。【代码】js-选项卡原理。_选项卡js原理
文章浏览阅读67次。原型模式是一种对象创建型模式,它采用复制原型对象的方法来创建对象的实例。它创建的实例,具有与原型一样的数据结构和值分为深度克隆和浅度克隆。浅度克隆:克隆对象的值类型(基本数据类型),克隆引用类型的地址;深度克隆:克隆对象的值类型,引用类型的对象也复制一份副本。UML图:具体代码:浅度复制:import java.util.List;/*..._prototype 设计模式
文章浏览阅读59次。入选国内首批云计算服务创新发展试点城市的北京、上海、深圳、杭州和无锡起到了很好的示范作用,不仅促进了当地产业的升级换代,而且为国内其他城市发展云计算产业提供了很好的借鉴。据了解,目前国内至少有20个城市确定将云计算作为重点发展的产业。这势必会形成新一轮的云计算基础设施建设的**。由于云计算基础设施建设具有投资规模大,运维成本高,投资回收周期长,地域辐射性强等诸多特点,各地在建...
文章浏览阅读9.4k次,点赞2次,收藏20次。一、功能及目的 在每个STM32的芯片上都有两个管脚BOOT0和BOOT1,这两个管脚在芯片复位时的电平状态决定了芯片复位后从哪个区域开始执行程序。BOOT1=x BOOT0=0 // 从用户闪存启动,这是正常的工作模式。BOOT1=0 BOOT0=1 // 从系统存储器启动,这种模式启动的程序_stm32boot0和boot1作用
文章浏览阅读3.4k次,点赞2次,收藏22次。C语言函数递归调用_c语言函数递归调用
文章浏览阅读410次。明日方舟bilibili服是一款天灾驾到战斗热血的创新二次元废土风塔防手游,精妙的二次元纸片人设计,为宅友们源源不断更新超多的纸片人老婆老公们,玩家将扮演废土正义一方“罗德岛”中的指挥官,与你身边的感染者们并肩作战。与同类塔防手游与众不同的几点,首先你可以在这抽卡轻松获得稀有,同时也可以在战斗体系和敌军走位机制看到不同。明日方舟bilibili服设定:1、起因不明并四处肆虐的天灾,席卷过的土地上出..._明日方舟抽卡模拟器
文章浏览阅读437次。Maven上传Jar到私服报错:ReasonPhrase: Repository version policy: SNAPSHOT does not allow version: xxx_repository version policy snapshot does not all
文章浏览阅读1.2k次。斐波那契数列(Fibonacci Sequence)是由如下形式的一系列数字组成的:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …上述数字序列中反映出来的规律,就是下一个数字是该数字前面两个紧邻数字的和,具体如下所示:示例:比如上述斐波那契数列中的最后两个数,可以推导出34后面的数为21+34=55下面是一个更长一些的斐波那契数列:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584,_斐波那契日
文章浏览阅读363次。PHP必会面试题1. 基础篇1. 用 PHP 打印出前一天的时间格式是 2017-12-28 22:21:21? //>>1.当前时间减去一天的时间,然后再格式化echo date('Y-m-d H:i:s',time()-3600*24);//>>2.使用strtotime,可以将任何字符串时间转换成时间戳,仅针对英文echo date('Y-m-d H:i:s',str..._//该层循环用来控制每轮 冒出一个数 需要比较的次数
文章浏览阅读1.3k次,点赞26次,收藏26次。windows下用mingw编译opencv貌似不支持cuda,选cuda会报错,我无法解决,所以没选cuda,下面两种编译方式支持。打开cmake gui程序,在下面两个框中分别输入opencv的源文件和编译目录,build-mingw为你创建的目录,可自定义命名。1、如果已经安装Qt,则Qt自带mingw编译器,从Qt安装目录找到编译器所在目录即可。1、如果已经安装Qt,则Qt自带cmake,从Qt安装目录找到cmake所在目录即可。2、若未安装Qt,则安装Mingw即可,参考我的另外一篇文章。_opencv mingw contrib
文章浏览阅读10w+次,点赞42次,收藏309次。今天给大家推荐5个好用且免费的简历模板网站,简洁美观,非常值得收藏!1、菜鸟图库https://www.sucai999.com/search/word/0_242_0.html?v=NTYxMjky网站主要以设计类素材为主,办公类素材也很多,简历模板大部个偏简约风,各种版式都有,而且经常会更新。最重要的是全部都能免费下载。2、个人简历网https://www.gerenjianli.com/moban/这是一个专门提供简历模板的网站,里面有超多模板个类,找起来非常方便,风格也很多样,无须注册就能免费下载,_hoso模板官网
文章浏览阅读142次。你听说过吗?该计划可让您以推广您的产品并在成功销售时支付佣金。它提供了新的营销渠道,使您的产品呈现在更广泛的受众面前并提高品牌知名度。此外,TikTok Shop联盟可以是一种经济高效的产品或服务营销方式。您只需在有人购买时付费,因此不存在在无效广告上浪费金钱的风险。这些诱人的好处是否足以让您想要开始您的TikTok Shop联盟活动?如果是这样,本指南适合您。_tiktok联盟