set的底层其实是由Map实现的
只是值为Object 不显示而已
注意 各种底层算法(哈希算法,二叉树算法,链表算法 )都只是针对map中的key!!
Map<k,v>以键值对的形式存在
Map接口一些常用的功能
1.添加功能Value put(K,V)
如果K相同则返回覆盖值V 如果没有为null
2.删除功能clear()
还有Value remove(Key) 根据键删除值! 返回键对应的值
3.判断功能
boolean containKey(key)
boolean containValue(Value)
boolean isEmpty()
4.获取功能
Collections< Values > .values()//获取map中所有的值 并构成集合
set< key >. KeySet()//获取map中所有的键 并构成集合
Map.entry<key,Value> . EntrySet( ) . //把Map中的键值对包装在一起 组成一个新集合!
也就是说看成一个新的对象 Map,Entry<key,Value>
5.长度功能
int size()
Map集合不能直接迭代
第一种方法
1.先获取所有的键值集合set
2.迭代器遍历集合
or
fore循环
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Demo2_Iterator {
/**
* 通过查看Map集合的api发现没有iterator方法,那么双列集合如何迭代呢?
* 根据键获取值
*/
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("张三", 23);
map.put("李四", 24);
map.put("王五", 25);
map.put("赵六", 26);
// Integer i = map.get("张三"); //根据键获取值
// System.out.println(i);
//获取所有的键
/*Set<String> keySet = map.keySet(); //获取所有键的集合
Iterator<String> it = keySet.iterator(); //获取迭代器
while(it.hasNext()) { //判断集合中是否有元素
String key = it.next(); //获取每一个键
Integer value = map.get(key); //根据键获取值
System.out.println(key + "=" + value);
}*/
//使用增强for循环遍历
for(String key : map.keySet()) { //map.keySet()是所有键的集合
System.out.println(key + "=" + map.get(key));
}
}
}
第二种 迭代方法
把双列集合变成单列集合
.entrySet()
Map.Entry<key,Value> 其子类为 Entry<key,Value>
接口.接口这样的用法 说明Entry是Map的子接口
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class Demo3_Iterator {
/**
* Map集合的第二种迭代,根据键值对对象,获取键和值
* A:键值对对象找键和值思路:
* 获取所有键值对对象的集合
* 遍历键值对对象的集合,获取到每一个键值对对象
* 根据键值对对象找键和值
*/
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("张三", 23);
map.put("李四", 24);
map.put("王五", 25);
map.put("赵六", 26);
//Map.Entry说明Entry是Map的内部接口,将键和值封装成了Entry对象,并存储在Set集合中
/*Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
//获取每一个对象
Iterator<Map.Entry<String, Integer>> it = entrySet.iterator();
while(it.hasNext()) {
//获取每一个Entry对象
Map.Entry<String, Integer> en = it.next(); //父类引用指向子类对象
//Entry<String, Integer> en = it.next(); //直接获取的是子类对象
String key = en.getKey(); //根据键值对对象获取键
Integer value = en.getValue(); //根据键值对对象获取值
System.out.println(key + "=" + value);
}*/
for(Entry<String, Integer> en : map.entrySet()) {
System.out.println(en.getKey() + "=" + en.getValue());
}
}
}
HashMap
自定义类要重写 equals 和hashcode方法
LinkedHashMap
怎么存就这么取
TreeMap
可以对键进行排序
自定义类的话(方法有两种)
法一:实现comparable接口并重写类中的compareTo
法二:加入比较器Comparator
小练习
判断每次字符出现的次数
import java.util.HashMap;
public class Main{
public static void main(String[] args) {
String s = "abbcccddddeeeeeeeeee";
char[] arr = s.toCharArray();
HashMap<Character,Integer> map =new HashMap<Character, Integer>();
for (char c : arr) {
map.put(c,map.containsKey(c) ? map.get(c)+1 : 1);
}
System.out.println(map);
}
}
HashMap嵌套
import java.util.HashMap;
import com.heima.bean.Student;
public class Demo8_HashMapHashMap {
/**
* * A:案例演示
* 集合嵌套之HashMap嵌套HashMap
*
* 需求:
* 双元课堂有很多基础班
* 第88期基础班定义成一个双列集合,键是学生对象,值是学生的归属地
* 第99期基础班定义成一个双列集合,键是学生对象,值是学生的归属地
*
* 无论88期还是99期都是班级对象,所以为了便于统一管理,把这些班级对象添加到双元课堂集合中
*/
public static void main(String[] args) {
//定义88期基础班
HashMap<Student, String> hm88 = new HashMap<>();
hm88.put(new Student("张三", 23), "北京");
hm88.put(new Student("李四", 24), "北京");
hm88.put(new Student("王五", 25), "上海");
hm88.put(new Student("赵六", 26), "广州");
//定义99期基础班
HashMap<Student, String> hm99 = new HashMap<>();
hm99.put(new Student("唐僧", 1023), "北京");
hm99.put(new Student("孙悟空",1024), "北京");
hm99.put(new Student("猪八戒",1025), "上海");
hm99.put(new Student("沙和尚",1026), "广州");
//定义双元课堂
HashMap<HashMap<Student, String>, String> hm = new HashMap<>();
hm.put(hm88, "第88期基础班");
hm.put(hm99, "第99期基础班");
//遍历双列集合
for(HashMap<Student, String> h : hm.keySet()) { //hm.keySet()代表的是双列集合中键的集合
String value = hm.get(h); //get(h)根据键对象获取值对象
//遍历键的双列集合对象
for(Student key : h.keySet()) { //h.keySet()获取集合总所有的学生键对象
String value2 = h.get(key);
System.out.println(key + "=" + value2 + "=" + value);
}
}
}
}
Hashtable
线程安全 效率低 命运和Vector一样被替代了
Collections 工具类的使用
只针对于list
Collecitons中的常见方法
public static < T > void sort(List< T > list)
public static < T > int binarySearch(List<?> list,T key)
public static < T > T max(Collection<?> coll)
public static void reverse(List<?> list)
public static void shuffle(List<?> list)
import java.util.ArrayList;
import java.util.Collections;
public class Demo1_Collecitons {
/**
* Collecitons中的常见方法
* public static <T> void sort(List<T> list)
public static <T> int binarySearch(List<?> list,T key)
public static <T> T max(Collection<?> coll)
public static void reverse(List<?> list)
public static void shuffle(List<?> list)
*/
public static void main(String[] args) {
//demo1();
//demo2();
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("c");
list.add("d");
list.add("g");
list.add("f");
//System.out.println(Collections.max(list)); //根据默认排序结果获取集合中的最大值
//Collections.reverse(list); //反转集合
Collections.shuffle(list); //随机置换,可以用来洗牌
System.out.println(list);
}
public static void demo2() {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("c");
list.add("d");
list.add("f");
list.add("g");
System.out.println(Collections.binarySearch(list, "c"));
System.out.println(Collections.binarySearch(list, "b")); //返回-2 为 :-插入值-1
}
public static void demo1() {
ArrayList<String> list = new ArrayList<>();
list.add("c");
list.add("a");
list.add("a");
list.add("b");
list.add("d");
System.out.println(list);
Collections.sort(list); //将集合排序
System.out.println(list);
}
}
最后小练习
模拟斗地主
1.存牌
ArrayList< Integer > list 存索引
HashMap<Integer,String> hm存 索引值和牌的内容
2.洗牌 洗索引
Collections.shuffle(list);
3.发牌 发索引
TreeSet< Integer > player1 = new TreeSet<>(); //拥有自动排序的功能
4.看牌 通过索引找到牌的内容并打印
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;
public class Main{
public static void main(String[] args) {
//1,买一副扑克,其实就是自己创建一个集合对象,将扑克牌存储进去
String[] num = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
String[] color = {"方片","梅花","红桃","黑桃"};
ArrayList<Integer> list = new ArrayList<>();
HashMap<Integer,String> hm = new HashMap<>();
int index = 0;
//拼接扑克牌并索引和扑克牌存储在hm中
for(String s1 : num) { //获取数字
for(String s2 : color) { //获取颜色
hm.put(index, s2.concat(s1));
list.add(index); //将索引0到51添加到list集合中
index++;
}
}
hm.put(index, "小王");
list.add(index);
index++;
hm.put(index, "大王");
list.add(index);
// 2.洗牌
Collections.shuffle(list);
// 3.发牌 添加的仅仅只是索引
TreeSet<Integer> player1 = new TreeSet<>();
TreeSet<Integer> player2 = new TreeSet<>();
TreeSet<Integer> me = new TreeSet<>();
TreeSet<Integer> dipai = new TreeSet<>();
for(int i = 0; i < list.size(); i++) {
if(i >= list.size() - 3) {
dipai.add(list.get(i)); //将三张底牌存储在底牌集合中
}else if(i % 3 == 0) {
player1.add(list.get(i));
}else if(i % 3 == 1) {
player2.add(list.get(i));
}else {
me.add(list.get(i));
}
}
// 4.看牌
lookPoker(hm,player1,"熊海涛");
lookPoker(hm,player2,"武晓慧");
lookPoker(hm,me,"杨瑞卿");
lookPoker(hm,dipai,"底牌");
}
public static void lookPoker(HashMap<Integer,String> hm,TreeSet<Integer> player,String name)
{
System.out.print(name+"的牌是:");
for(Integer i : player) {
System.out.print(hm.get(i)+" ");
}
System.out.println();
}
}
所以最后的牌是按照顺序打印的
泛型固定上边界
? extends E
用于addAll(Collection c)
表示向父类集合可以添加子类集合
泛型固定下边界
? super E
用于TreeSet 或TreeMap 中的比较器方法中
表示父类的比较器 子类也能用
演示代码
import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeSet;
import com.heima.bean.BaseStudent;
import com.heima.bean.Student;
public class Demo2_Genric {
/**
* 泛型固定下边界
* ? super E
*
* 泛型固定上边界
* ? extends E
*/
public static void main(String[] args) {
//demo1();
TreeSet<Student> ts1 = new TreeSet<>(new CompareByAge());
ts1.add(new Student("张三", 33));
ts1.add(new Student("李四", 13));
ts1.add(new Student("王五", 23));
ts1.add(new Student("赵六", 43));
TreeSet<BaseStudent> ts2 = new TreeSet<>(new CompareByAge());
ts2.add(new BaseStudent("张三", 33));
ts2.add(new BaseStudent("李四", 13));
ts2.add(new BaseStudent("王五", 23));
ts2.add(new BaseStudent("赵六", 43));
System.out.println(ts2);
}
public static void demo1() {
ArrayList<Student> list1 = new ArrayList<>();
list1.add(new Student("张三", 23));
list1.add(new Student("李四", 24));
ArrayList<BaseStudent> list2 = new ArrayList<>();
list2.add(new BaseStudent("王五", 25));
list2.add(new BaseStudent("赵六", 26));
list1.addAll(list2);
}
}
class CompareByAge implements Comparator<Student> {
@Override
public int compare(Student s1, Student s2) {
int num = s1.getAge() - s2.getAge();
return num == 0 ? s1.getName().compareTo(s2.getName()) : num;
}
}