@一贤不穿小鞋
1.为什么学Map
- 很多Java技术的底层采用了Map.
2.HashMap:按key-value对方式存值.它的key无序的唯一的单一对象.底层采用数组+链表结构存值.
- 优点:key可去重.
- key的唯一性(去重):通过key的泛型所在的类重写hashCode()和equals()保证key的唯一性的.
import java.util.*;
public class Test4 {
public static void main(String[] args) {
Map m=new HashMap();
m.put("CN", "中华人民共和国");
m.put("RU", "俄罗斯联邦");
m.put("US", "美利坚合众国");
System.out.println(m.get("CN"));
System.out.println(m.size());
System.out.println("包含吗?"+m.containsKey("RU"));
System.out.println("包含吗?"+m.containsKey("XX"));
System.out.println(m.keySet());
System.out.println(m.values());
System.err.println(m);//输出3,下面被删除了,没输出3
m.clear();
System.out.println(m.size());//输出0
}
}
import java.util.*;
public class Test4 {
public static void main(String[] args) {
Map m=new HashMap();
m.put("CN", "中华人民共和国");
m.put("RU", "俄罗斯联邦");
m.put("US", "美利坚合众国");
System.out.println(m.get("CN"));
System.out.println(m.size());
System.out.println("包含吗?"+m.containsKey("RU"));
System.out.println("包含吗?"+m.containsKey("XX"));
System.out.println(m.keySet());
System.out.println(m.values());
System.err.println(m);//输出3,下面被删除了,没输出3
System.out.println("-----开始遍历输出-------");
//使用迭代器
Iterator it=m.keySet().iterator();
while (it.hasNext()) {
String key=it.next().toString();
System.out.println(key+"\t"+m.get(key));
}
System.out.println("------------");
//增强的for foreach
for (Object k: m.keySet()) {
System.out.println(k+"\t"+m.get(k));
}
}
}
eg:public static void main(String[] args) {
//创建map集合对象
HashMap<Integer, String> map1=new HashMap();
//向集合中添加元素
map1.put(6, "hh");
map1.put(3, "kk");
map1.put(8, "qq");
map1.put(1, "aa");
map1.put(6, "bb");
map1.put(null, null);
/*第一种:遍历map集合*/
//将map集合中key-value当作一个整体entry,将map集合转换为set集合
Set<Entry<Integer, String>> set1= map1.entrySet();
//遍历set集合
for (Entry<Integer, String> e1 : set1) {
System.out.println("当前entry对象为:"+e1+
",key为:"+e1.getKey()+",value为:"+e1.getValue());
}
System.out.println("-----------------------------");
//删除集合中元素
map1.remove(3);
/*第二种:遍历map集合*/
//获得map集合中所有key的集合
Set<Integer> keys=map1.keySet();
//获得集合跌代器对象
Iterator<Integer> it1=keys.iterator();
//每判断一次跌代一次
while (it1.hasNext()) {
Integer key1=it1.next();
System.out.println("key为:"+key1+",value为:"+map1.get(key1));
}
}
3.TreeMap:按key-value对方式存值.它的key无序可排序的唯一的单一对象.底层二叉树结构存值.
- 注意:TreeMap一定要用排序器.如果TreeMap的构造方法没有传递排序器对象,默认用自然排序器,要求TreeMap的key的泛型所在类实现自然排序器(Comparable)接口,重写排序方法;如果TreeMap的构造方法传递自定义排序器对象,那就用这个排序对象的排序方法.
- 优点:key可排序,唯一的(去重).
- key的排序性:通过排序器的排序方法返回负数排在前面(左子节点),返回正数排在后面(右子节点).
- key的唯一性(去重):通过排序器的排序方法返回0来实现去重的.
eg:public static void main(String[] args) {
//创建map集合
Map<Integer, String> map3=new TreeMap();
//向集合中添加元素
map3.put(6, "hh");
map3.put(3, "cc");
map3.put(8, "kk");
map3.put(4, "aa");
map3.put(5, "bb");
map3.put(7, "cc");
map3.put(9, "ff");
map3.put(6, "ee");
//TreeMap的key不能为null
map3.put(10, null);
/*第一种:遍历map集合*/
//将key-value对当作一个整体entry,将map集合转换为set集合
Set<Entry<Integer, String>> set3=map3.entrySet();
//用跌代器遍历set集合
Iterator<Entry<Integer, String>> it3=set3.iterator();
while (it3.hasNext()) {
Entry<Integer, String> e3=it3.next();
System.out.println("key为:"+e3.getKey()+",value为:"+e3.getValue());
}
System.out.println("********************************");
//删除集合中元素
map3.remove(9);
/*第二种:遍历map集合*/
//获得map集合中所有Key
Set<Integer> set4=map3.keySet();
for (Integer k : set4) {
System.out.println("key为:"+k+",value为:"+map3.get(k));
}
}
4.排序器:
4.1:自然排序器(Comparable)
eg:/**
* 猫类,实现自然排序器接口重写排序方法
* @author sx
* @version 1.0 2020年10月27日
*/
public class Cat implements Comparable<Cat>{
public String nickName;
public String breed;
public Cat() {
}
public Cat(String nickName, String breed) {
super();
this.nickName = nickName;
this.breed = breed;
}
@Override
public String toString() {
return "Cat [nickName=" + nickName + ", breed=" + breed + "]";
}
/**
* 重写父接口中排序方法
* @param this 指代当前要添加key-value的key
* @param o 指代从根节点开始每个要比较节点的Key
* @return in 返回负数排在前面,返回正数排在后面,返回0表示key相同
* 排序规则:先根据昵称升序排序,昵称相同再根据品种降序排序
*/
@Override
public int compareTo(Cat o) {
if (this.nickName.compareTo(o.nickName)!=0) {//昵称不同
return this.nickName.compareTo(o.nickName);
} else {//昵称相同
return -this.breed.compareTo(o.breed);
}
}
}
public static void main(String[] args) {
//创建map集合
TreeMap<Cat, Integer> map4=new TreeMap();
//向集合中添加元素
map4.put(new Cat("c猫", "c类"), 6);
map4.put(new Cat("a猫", "a类"), 1);
map4.put(new Cat("b猫", "b类"), 7);
map4.put(new Cat("f猫", "c类"), 2);
map4.put(new Cat("c猫", "a类"), 3);
map4.put(new Cat("c猫", "c类"), 9);
/*第一种:遍历map集合*/
//key-value当作一个整体entry,将map集合转换为set集合
Set<Entry<Cat, Integer>> set4=map4.entrySet();
for (Entry<Cat, Integer> e4 : set4) {
System.out.println("key为:"+e4.getKey()+","+e4.getValue());
}
System.out.println("*********************************");
//删除集合中元素
map4.remove(new Cat("f猫", "c类"));
/*第一种:遍历map集合*/
//key-value当作一个整体entry,将map集合转换为set集合
Set<Entry<Cat, Integer>> set5=map4.entrySet();
for (Entry<Cat, Integer> e4 : set5) {
System.out.println("key为:"+e4.getKey()+","+e4.getValue());
}
}
4.2:自定义排序器(Comparator)
eg:/**
* 自定义排序器类
* @author sx
* @version 1.0 2020年10月27日
*/
public class MyComparator implements Comparator<Cat7>{
/**
* 重写父接口中排序方法
* @param o1 要添加的key-value中key
* @param o2 表示从根节点开始每个要比较的节点的key
* @return int 返回负数表示排在前面,返回正数排在后面,返回0表示key相同
* 排序规则:先按昵称降序排序,昵称相同再按品种升序排序
*/
@Override
public int compare(Cat7 o1, Cat7 o2) {
if (o1.nickName.compareTo(o2.nickName)!=0) {
return -o1.nickName.compareTo(o2.nickName);
} else {//昵称相同
return o1.breed.compareTo(o2.breed);
}
}
}
public static void main(String[] args) {
//创建自定义排序器的对象
MyComparator mc=new MyComparator();
//创建map集合,将自定义排序器的对象作为TreeMap构造方法参数
TreeMap<Cat7, Integer> map4=new TreeMap(mc);
//向集合中添加元素
map4.put(new Cat7("c猫", "c类"), 6);
map4.put(new Cat7("a猫", "a类"), 1);
map4.put(new Cat7("b猫", "b类"), 7);
map4.put(new Cat7("f猫", "c类"), 2);
map4.put(new Cat7("c猫", "a类"), 3);
map4.put(new Cat7("c猫", "c类"), 9);
/*第一种:遍历map集合*/
//key-value当作一个整体entry,将map集合转换为set集合
Set<Entry<Cat7, Integer>> set4=map4.entrySet();
for (Entry<Cat7, Integer> e4 : set4) {
System.out.println("key为:"+e4.getKey()+","+e4.getValue());
}
System.out.println("*********************************");
//删除集合中元素
map4.remove(new Cat7("f猫", "c类"));
/*第一种:遍历map集合*/
//key-value当作一个整体entry,将map集合转换为set集合
Set<Entry<Cat7, Integer>> set5=map4.entrySet();
for (Entry<Cat7, Integer> e4 : set5) {
System.out.println("key为:"+e4.getKey()+","+e4.getValue());
}
}
4.3:匿名内部类自定义排序器
eg:public static void main(String[] args) {
//创建map集合,将自定义排序器的对象作为TreeMap构造方法参数
TreeMap<Cat8, Integer> map4=new TreeMap(new Comparator<Cat8>() {
/**
* 重写父接口中排序方法
* @param o1 要添加的key-value中key
* @param o2 表示从根节点开始每个要比较的节点的key
* @return int 返回负数表示排在前面,返回正数排在后面,返回0表示key相同
* 排序规则:先按昵称降序排序,昵称相同再按品种升序排序
*/
@Override
public int compare(Cat8 o1, Cat8 o2) {
if (o1.nickName.compareTo(o2.nickName)!=0) {
return -o1.nickName.compareTo(o2.nickName);
} else {//昵称相同
return o1.breed.compareTo(o2.breed);
}
}
});
//向集合中添加元素
map4.put(new Cat8("c猫", "c类"), 6);
map4.put(new Cat8("a猫", "a类"), 1);
map4.put(new Cat8("b猫", "b类"), 7);
map4.put(new Cat8("f猫", "c类"), 2);
map4.put(new Cat8("c猫", "a类"), 3);
map4.put(new Cat8("c猫", "c类"), 9);
/*第一种:遍历map集合*/
//key-value当作一个整体entry,将map集合转换为set集合
Set<Entry<Cat8, Integer>> set4=map4.entrySet();
for (Entry<Cat8, Integer> e4 : set4) {
System.out.println("key为:"+e4.getKey()+","+e4.getValue());
}
System.out.println("*********************************");
//删除集合中元素
map4.remove(new Cat8("f猫", "c类"));
/*第一种:遍历map集合*/
//key-value当作一个整体entry,将map集合转换为set集合
Set<Entry<Cat8, Integer>> set5=map4.entrySet();
for (Entry<Cat8, Integer> e4 : set5) {
System.out.println("key为:"+e4.getKey()+","+e4.getValue());
}
}
5.(了解)Hashtable:哈希表.线程安全,运行效率慢;不允许null作为key或者是value.
6.(了解)HashMap VS HashTable:(面试)
6.1:相同点
- 都可以按key-value对方式存值,它的key无序的唯一的单一对象.底层采用数组+链表结构存值.
6.2:不同点:
6.2.1:推出时间不同
- HashMap 在jdk1.2之后推出的;
- HashTable在jdk1.2之前就推出了.
6.2.2:初始容量和扩容
- HashMap初始容量为16,一般情况下按原来2倍扩容的;
- HashTable初始容量为11,一般情况下按原来2倍+1扩容的;
6.2.3:线程和效率不同
- HashMap在多线程中使用不安全,但是在单线程中使用效率高;
- HashTable在多线程中使用安全,但是在单线程中使用效率低;
6.2.4:存null不同
- HashMap的key和value都可以存null;
- HashTable的key和value都不可以存null;
6.2.5:方法
- HashTable拥有HashMap所有的方法,还有自己独有方法.
7.(了解)Properties:继承自HashTable,按key-value对的方式存值,核心作用是可以通过流来动态加载配置文件.
总结:
1.TreeSet(重点)
2.HashMap(重点)
3.TreeMap(重点)
1.ArrayList:存储有序的可重复的单一对象.底层采用Object[]结构存值.
- 优点:访问遍历和修改元素效率高.按顺序添加元素的效率也高.
- 缺点:删除元素和按指定索引添加元素效率低.
2.LinkedList:存储有序的可重复的单一对象.底层采用双向链表结构存值.
- 优点:删除和添加元素的效率高.
- 缺点:访问遍历和修改元素的效率低.
3.HashSet:存储无序的唯一的单一对象.底层采用HashMap的Key存值.
- 注意:HashSet泛型所在类中必须重写hashCode()和equals().
- 优点:去重(唯一性).
- 唯一性:通过HashSet泛型所有在类中重写hashCode()和equals()来实现去重的.
4.TreeSet:存储无序的可排序的唯一的单一对象.底层采用TreeMap的Key存值.
- 注意:TreeSet一定要用排序器.如果TreeSet的构造方法中没有传递自定义排序器对象,默认自然排序器,要求TreeSet的泛型所在类中要实现自然排序器接口(Comparable),重写排序方法compareTo();如果TreeSet的构造方法中传递自定义排序器对象,就要按自定义排序器对象中排序方法compare()来排序.
- 优点:可排序和去重.
- 可排序性:通过排序器的排序方法返回负数排在前面,返回正数排在后面.
- 唯一性(去重):通过排序器的排序方法返回0,表示相同元素不存.
5.HashMap:按key-value对方式存值,它的key无序的唯一的单一对象.底层采用数组+链表结构存值.
- 注意:HashMap的key的泛型所在类中必须重写hashCode()和equals().
- 优点:key去重.
- key的唯一性(去重):通过key的泛型所在类中重写hashCode()和equals()来实现去重的.
6.TreeMap:按key-value的方式存值,它的key无序的可排序的唯一的单一对象.底层采用二叉树结构存值.
- 注意:TreeMap一定要用排序器.如果TreeMap的构造方法中没有传递自定义排序器对象,默认自然排序器,要求TreeMap的Key的泛型所在类中要实现自然排序器接口(Comparable),重写排序方法compareTo();如果TreeMap的构造方法中传递自定义排序器对象,就要按自定义排序器对象中排序方法compare()来排序.
- 优点:key可以排序和去重.
- key的可排序性:通过排序器的排序方法返回负数排在前面,返回正数排在后面.
- key的唯一性:通过排序器的排序方法返回0,表示相同元素不存.
7.对一列相同类型的数据进行去重
- 可以用HashSet,TreeSet,HashMap和TreeMap去重,首选HashSet来实现去重.
8.对一列相同类型的数据进行排序
- 可以用TreeSet和TreeMap,首选TreeSet进行排序.
- 还可以用其他集合结合排序方法实现.