java基础第十四篇之Map

一,Map集合的特点: * * 1.Map集合和Collection集合,没有关系 * * 2.Map集合的元素是成对存在(夫妻关系) * Collection集合的元素是独立存在的(单身关系) * * 3.Map集合的元素不能重复(是元素的key值不能重复) * * 总结: * Collection集合我们一般称为单列集合 * Map集合我们称为双列集合 * 二,Map接口下常用的实现类 * * HashMap<K,V>:底层是哈希表结构,无序的(存取顺序不一致) * * * LinkedHashMap<K,V>:底层链表+哈希表结构,有序的(存取顺序一致) * 这里<K,V>是两个泛型,这里的K和V可以相同 也可以不同 * K代表键的类型,V代表的是值的类型 * * 以上所有的实现类,保证键的唯一性(键不能重复),那么我们需要重写K这种类型的hashCode和equals方法 * 比如:K的类型是String,Integer...(java提供的类型),那么我们不需要管他 * K的类型是Person,Dog等自定义类型 那么我们就需要重写hashCode和equals方法 * * 三,Map接口中定义的常用方法: * * 1.增加: * public V put(K key,V value);//向Map集合中添加一个元素(键值对) * 返回值:表示被新的键值对 覆盖的那个旧的键值对的值 * 如果没有覆盖,返回值是null * * 2.删除: * public V remove(Object key);//删除一个键值对(根据键来删除) * * 3.改:实际上就是put方法,只要put的时候键和map集合中原有的键重复,就可以达到改的目的 * * 4.查 * public V get(Object key);//根据键 来查找键所对应的值 public interface InterfaceA { public abstract void showA(); interface InterfaceB{//内部接口 public abstract void showB(); } }

//定义一个类 去实现接口

class MyClass1 implements InterfaceA{

@Override public void showA() { // TODO Auto-generated method stub }

// @Override // public void showA() { // // TODO Auto-generated method stub // // } }

class MyClass2 implements InterfaceA.InterfaceB{

@Override public void showB() { // TODO Auto-generated method stub } }

/* * 1.因为Map集合 和Collection集合 没有继承关系 * map集合中是没有迭代器 * * 2.java为map集合提供了另外两种迭代的方式: * 方式一:以键找值的方法: * 获取所有的键的集合 map.keySet(); * 方式二:键值对的方式 * public Set<Map.Entry<K,V>> entrySet() */ //创建内部类对象 //OuterClass.InnerClass oi = new OuterClass().new InnerClass(); Map<String, Integer> map = new HashMap<String, Integer>(); map.put("张三", 18); map.put("李四", 28); map.put("王五", 38); map.put("赵六", 48); //1.获取map集合的entry 集合 Set<Map.Entry<String, Integer>> entries = map.entrySet(); //2.用迭代器 遍历这个entries这个Set集合 Iterator<Map.Entry<String, Integer>> it = entries.iterator(); //3.遍历 while(it.hasNext()){ Map.Entry<String, Integer> entry = it.next(); //一个entry中 有两个属性 String key = entry.getKey(); Integer value = entry.getValue(); System.out.println(key+"="+value); } * 练习1:使用map存储:键为学号,值为一个学生的对象,学生对象有属性(姓名,年龄) * * * 练习2:使用map存储:键为学生(姓名,年龄)值为学生自己的家庭住址。 * Map<Student,String> public class MapDemo { public static void main(String[] args) { //定义一个Map集合 存储键为学生(姓名,年龄)值为学生自己的家庭住址。 Map<Student, String> map = new HashMap<Student, String>(); //向集合添加数据 map.put(new Student("王宝强", 40), "北京五环外"); map.put(new Student("谢霆锋", 50), "北京180环外"); map.put(new Student("马蓉", 45), "上海交通路"); map.put(new Student("郭德纲", 55), "广州德云社"); map.put(new Student("马蓉", 45), "我家"); //map判断键重复不重复,是通过hashCode和equals方法 //如果 我要求一个学生的姓名和年龄一样 就认为是同一个学生 //遍历集合 keySet entrySet //1.获取entry的集合 Set<Map.Entry<Student, String>> entries = map.entrySet(); //2.迭代器遍历 foreach for (Map.Entry<Student, String> entry : entries) { Student key = entry.getKey(); String value = entry.getValue(); System.out.println(key+"="+value); } } }

/* * LinkedHashMap: 采用链表+哈希表结构 * 元素是有序的 Collection和Map都可以嵌套 * * ArrayList<ArrayList<String>> * * ArrayList<Map<K,V>> * * Map<String,ArrayList<String>> * * Map<String,Map<String,Student>> * * 比如我们传智博客学生(有iOS Android UI JavaEE) * Map<学号,学生> UI = new HashMap<学号,学生>(); * * Map<学号,学生> JavaEE = new HashMap<学号,学生>(); * * Map<学号,学生> android = new HashMap<学号,学生>(); * * * ArrayList<Map<学号,学生>> al= new .... * al.add(UI); * al.add(JavaEE); * al.add(android); * * Map<学院名,Map<学号,学生>> map = new .... * map.put("UI学院",UI); * map.put("JavaEE学院",JavaEE); * map.put("安卓学院",android); * * * * * */ public class MapMapDemo {

public static void main(String[] args) { // TODO Auto-generated method stub //1.创建一个UI学院的map集合 Map<String, Student> uiMap = new HashMap<String, Student>(); uiMap.put("黑马001", new Student("小丽", 18)); uiMap.put("黑马003", new Student("小美", 19)); uiMap.put("黑马004", new Student("小雨", 20)); //2.创建一个JavaEE学院map集合 Map<String, Student> eeMap = new HashMap<String, Student>(); eeMap.put("黑马001", new Student("小诗", 18)); eeMap.put("黑马002", new Student("小公", 19)); eeMap.put("黑马004", new Student("小龙", 20)); //3.创建一个android学院map集合 Map<String, Student> anMap = new HashMap<String, Student>(); anMap.put("黑马002", new Student("小k", 18)); anMap.put("黑马003", new Student("小Q", 19)); anMap.put("黑马004", new Student("小A", 20)); //4.定义一个存储所有学院名字和map对象的集合 Map<String,Map<String, Student>> map = new HashMap<String, Map<String,Student>>(); map.put("UI学院", uiMap); map.put("EE学院", eeMap); map.put("AN学院", anMap); //遍历map 打印是每一个学生 //1.keySet() 2.entrySet() Set<Map.Entry<String,Map<String, Student>>> entries = map.entrySet(); //2.遍历 entries 迭代器,foreach Iterator<Map.Entry<String,Map<String, Student>>> it = entries.iterator(); //标准代码 while(it.hasNext()){ Map.Entry<String,Map<String, Student>> entry = it.next(); String key = entry.getKey(); Map<String, Student> valueMap = entry.getValue(); //遍历value这个map集合 keySet entrySet Set<Map.Entry<String, Student>> xyentries = valueMap.entrySet(); //迭代器 foreach Iterator<Map.Entry<String, Student>> xyit = xyentries.iterator(); //标准代码 while(xyit.hasNext()){ Map.Entry<String, Student> xyentry = xyit.next(); String xykey = xyentry.getKey(); Student xyValue = xyentry.getValue(); //System.out.println("学院,学号,学生名字,学生年龄"); System.out.println(key+"-"+xykey+"-"+xyValue.getName()+"-"+xyValue.getAge()); } } }

}

* Collections集合工具类中的两个方法: * * public static void sort(List<T> list);//按照自然顺序(123 321 abc cba)排序一个List集合 * * public static void shuffle(List<?> list);//打乱集合中顺序 * 可变参数: 这里说的可变 不是参数的数据类型 而是参数的个数 * JDK1.5之后的新特性 * * 格式: public void showNum(int... num){ * * } * * 注意事项: * 当一个方法具有多个参数,而且其中有一个是可变参数,那么可变参数必须写到 参数的最后一个 * public class VariableArgDemo01 {

public static void main(String[] args) { // TODO Auto-generated method stub // show(1); // show(1,2); // show(1,2,3); show(1,2,3,4,5); } //定义带有可变参数的方法 public static void show(int count,int... num){ //在方法中怎么获取实际传递进来的参数,可变参数本质就是一个数组 System.out.println(num.length); for (int i = 0; i < num.length; i++) { System.out.println(num[i]); } } }

/* * 1.定义自定义规则的map集合 * * 2.产生一副牌(存储的是序号) * * 3.洗牌(序号的集合) * * 4.发牌(发的就是序号) * * 5.要求三个玩家以及地主牌进行排序(sort方法) * * 6.看牌(根据序号从自定义的map集合中取值) * * */ public class DouDiZhuDemo {

public static void main(String[] args) { // TODO Auto-generated method stub //1.定义规则的map集合 Map<Integer, String> map = new LinkedHashMap<Integer, String>(); //2.定义一个牌集合 ArrayList<Integer> cards = new ArrayList<Integer>(); //添加牌 一张牌 数值+花色 String[] nums = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"}; String[] colors = {"♠","♥","♣","♦"}; //拼接一个张牌 int id = 54;//1234 for (String num : nums) { for (String color : colors) { String card = color+num; map.put(id, card); cards.add(id); id--; //System.out.println(card); } } //添加大王小王 map.put(2, "小S"); cards.add(2); map.put(1, "大S"); cards.add(1); //3.洗牌 Collections.shuffle(cards); //4.发牌 //定义三个集合 ArrayList<Integer> p1 = new ArrayList<Integer>(); ArrayList<Integer> p2 = new ArrayList<Integer>(); ArrayList<Integer> p3 = new ArrayList<Integer>(); //定义地主牌的集合 ArrayList<Integer> dp = new ArrayList<Integer>(); //遍历54张牌 for (int i = 0; i < cards.size(); i++) { Integer card = cards.get(i); //如果是最后三张,不发,保存到地主牌的集合中 //i 53 52 51 if(i>=51){ //不发 dp.add(card); }else{ //0 p1 1 p2 2 p3 3 p1 if(i%3==0){ //给p1发牌 p1.add(card); }else if(i%3==1){ p2.add(card); }else{ p3.add(card); } } } //5.排序 Collections.sort(p1); Collections.sort(p2); Collections.sort(p3); Collections.sort(dp); //看牌 lookCards(p1,map); lookCards(p2,map); lookCards(p3,map); lookCards(dp,map); } /* * 看牌 */ public static void lookCards(ArrayList<Integer> cards,Map<Integer, String> map){ //根据每一张的编号从 map中取出打印 for (Integer id : cards) { String card = map.get(id); System.out.print(card+" "); } System.out.println(); }

}

/*

Map 里面有个方法: boolean containsKey : 判断Map集合中是否包含指定值

HashSet:底层是哈希算法实现. LinkedHashSet:底层是链表实现,但是也是可以保证元素唯一,和HashSet原理一样.

TreeSet:底层是二叉树算法实现. 一般在开发的时候不需要对存储的元素排序,所有在开发的时候大多用HashSet,HashSet的效率比较高 TreeSet在面试的时候比较多,问你有几种排序方式,和几种排序方式的区别?

2. TreeSet总结 1). TreeSet的特点 (1). 可以对元素进行排序 有两种排序方式。 (2). TreeSet保证元素的唯一性依据 在实现的Comparable的compareTo或者Comparator的compare方法中,如果这两个方法的返回值为0,那么TreeSet就认为这两个元素一样。按照Set的唯一性规则,在一次重复的元素不能被添加到TreeSet这个集合中。 2). TreeSet的两种排序方式 (1). 让元素本身具有比较性 元素本身要实现Comparable接口并实现里面的compareTo方法以保证元素本身具有比较性 (2). 让容器自身具有比较性 当元素本身不具有比较性或者具备的比较性不是所需要的,就在TreeSet建立实例的时候,传入Comparator接口的实现子类的实例。这个Comparator子类必须实现compare方法。 (3). 元素的可存储性 [1]. 自定义的类,如果重写了hashCode和equals两个方法,可以存入HashSet容器 [2]. 自定义的类,如果实现了Comparable的compareTo()方法,可以存入TreeSet容器。 【总结】如果自定义的类既重写了hashCode和equals,又实现了compareTo,那么这个类的元素既可以存入HashSet容器,也可以存入TreeSet容器。

Map HashMap :底层是哈希算法,针对键 LinkedHashMap:底层是链表,针对键. TreeMap:底层是二叉树算法,针对键.(开发中HashMap比较多) Collection List(存取有序,有索引,可以重复) ArrayList:底层是数组实现的,线程不安全,查找和修改快,增和删比较慢. LinkedList:底层是链表实现的,线程不安全,增和删比较快,查找和修改比较慢 Vector : 底层是数组实现的,线程安全的,无论增删改查都慢. 如果查找和修改多,用ArrayList. 如果增和删多,用LinkedList. 如果都多,用ArrayList Set(存取无序,无索引,不可以重复) HashSet LinkedHashSet TreeSet

//获取字符串中每个字符的个数 public class Demo11 { public static void main(String[] args) { String sbc = "kalsdjfoisoigjsljlfklkadaooaijfa"; //将字符串变成一个字符数组 char[] chs = sbc.toCharArray(); //遍历这个字符数组,一个一个的进行比较,但是要计算数量,那么用那个集合好点?Map,为什么Map,可以显示效果,'a',1 'b'2 Map<Character, Integer> map = new HashMap<>(); //遍历字符数组 for(char c : chs) { //判断Map里面有没有键是c的? boolean flag = map.containsKey(c); //代表map里面有键是c的,那么数量就需要++ if(flag) { //在原先的数量上加上1,根据键找值 map.put(c, map.get(c)+1); }else { //就是map集合里面没用这个字符,如果说是没有的话,那么说明是第一次. map.put(c, 1); } } System.out.println(map); } }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券