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);
}
}
}
文章浏览阅读331次。第一部分:准备工作1 安装虚拟机2 安装centos73 安装JDK以上三步是准备工作,至此已经完成一台已安装JDK的主机第二部分:准备3台虚拟机以下所有工作最好都在root权限下操作1 克隆上面已经有一台虚拟机了,现在对master进行克隆,克隆出另外2台子机;1.1 进行克隆21.2 下一步1.3 下一步1.4 下一步1.5 根据子机需要,命名和安装路径1.6 ..._创建一个hadoop项目
文章浏览阅读1.7k次。心脏滴血漏洞HeartBleed CVE-2014-0160 是由heartbeat功能引入的,本文从深入码层面的分析该漏洞产生的原因_heartbleed代码分析
文章浏览阅读1.4k次。前言ofd是国家文档标准,其对标的文档格式是pdf。ofd文档是容器格式文件,ofd其实就是压缩包。将ofd文件后缀改为.zip,解压后可看到文件包含的内容。ofd文件分析工具下载:点我下载。ofd文件解压后,可以看到如下内容: 对于xml文件,可以用文本工具查看。但是对于印章文件(Seal.esl)、签名文件(SignedValue.dat)就无法查看其内容了。本人开发一款ofd内容查看器,..._signedvalue.dat
文章浏览阅读1.8w次,点赞29次,收藏313次。整体系统设计本设计主要是对ADC和DAC的使用,主要实现功能流程为:首先通过串口向FPGA发送控制信号,控制DAC芯片tlv5618进行DA装换,转换的数据存在ROM中,转换开始时读取ROM中数据进行读取转换。其次用按键控制adc128s052进行模数转换100次,模数转换数据存储到FIFO中,再从FIFO中读取数据通过串口输出显示在pc上。其整体系统框图如下:图1:FPGA数据采集系统框图从图中可以看出,该系统主要包括9个模块:串口接收模块、按键消抖模块、按键控制模块、ROM模块、D.._基于fpga的信息采集
文章浏览阅读2.5w次。1.背景错误信息:-- [http-nio-9904-exec-5] o.s.c.n.z.filters.post.SendErrorFilter : Error during filteringcom.netflix.zuul.exception.ZuulException: Forwarding error at org.springframework.cloud..._com.netflix.zuul.exception.zuulexception
文章浏览阅读358次。1.介绍图的相关概念 图是由顶点的有穷非空集和一个描述顶点之间关系-边(或者弧)的集合组成。通常,图中的数据元素被称为顶点,顶点间的关系用边表示,图通常用字母G表示,图的顶点通常用字母V表示,所以图可以定义为: G=(V,E)其中,V(G)是图中顶点的有穷非空集合,E(G)是V(G)中顶点的边的有穷集合1.1 无向图:图中任意两个顶点构成的边是没有方向的1.2 有向图:图中..._给定一个邻接矩阵未必能够造出一个图
文章浏览阅读321次。(十二)、WDS服务器安装通过前面的测试我们会发现,每次安装的时候需要加域光盘映像,这是一个比较麻烦的事情,试想一个上万个的公司,你天天带着一个光盘与光驱去给别人装系统,这将是一个多么痛苦的事情啊,有什么方法可以解决这个问题了?答案是肯定的,下面我们就来简单说一下。WDS服务器,它是Windows自带的一个免费的基于系统本身角色的一个功能,它主要提供一种简单、安全的通过网络快速、远程将Window..._doc server2012上通过wds+mdt无人值守部署win11系统.doc
文章浏览阅读219次。python–xlrd/xlwt/xlutilsxlrd只能读取,不能改,支持 xlsx和xls 格式xlwt只能改,不能读xlwt只能保存为.xls格式xlutils能将xlrd.Book转为xlwt.Workbook,从而得以在现有xls的基础上修改数据,并创建一个新的xls,实现修改xlrd打开文件import xlrdexcel=xlrd.open_workbook('E:/test.xlsx') 返回值为xlrd.book.Book对象,不能修改获取sheett_xlutils模块可以读xlsx吗
文章浏览阅读8.2w次,点赞267次,收藏656次。运行Selenium出现'WebDriver' object has no attribute 'find_element_by_id'或AttributeError: 'WebDriver' object has no attribute 'find_element_by_xpath'等定位元素代码错误,是因为selenium更新到了新的版本,以前的一些语法经过改动。..............._unresolved attribute reference 'find_element_by_id' for class 'webdriver
文章浏览阅读198次。一:模态窗口//父页面JSwindow.showModalDialog(ifrmehref, window, 'dialogWidth:550px;dialogHeight:150px;help:no;resizable:no;status:no');//子页面获取父页面DOM对象//window.showModalDialog的DOM对象var v=parentWin..._jquery获取父window下的dom对象
文章浏览阅读1.7w次,点赞15次,收藏129次。算法(algorithm)是解决一系列问题的清晰指令,也就是,能对一定规范的输入,在有限的时间内获得所要求的输出。 简单来说,算法就是解决一个问题的具体方法和步骤。算法是程序的灵 魂。二、算法的特征1.可行性 算法中执行的任何计算步骤都可以分解为基本可执行的操作步,即每个计算步都可以在有限时间里完成(也称之为有效性) 算法的每一步都要有确切的意义,不能有二义性。例如“增加x的值”,并没有说增加多少,计算机就无法执行明确的运算。 _算法
文章浏览阅读1.5k次,点赞18次,收藏26次。网络安全的标准和规范是网络安全领域的重要组成部分。它们为网络安全提供了技术依据,规定了网络安全的技术要求和操作方式,帮助我们构建安全的网络环境。下面,我们将详细介绍一些主要的网络安全标准和规范,以及它们在实际操作中的应用。_网络安全标准规范