1.Map集合的特点:
1.1键值对的形式存储数据
详解如下:
package com.Kissship.map; import java.util.HashMap; import java.util.Map; /** * Map集合的特点 * 1.键值对的形式存储数据(论证:增删改查) * 2.Key可以为空 * * * @author jj * */ public class Demo1 { public static void main(String[] args) { Map map = new HashMap(); //增加 map.put("name", "李青");//(键值对形式) map.put("age", 22); map.put("sex", "男"); map.put("money", 4800); //查询 System.out.println("原始数据:"+map);//打印 System.out.println("键:"+map.keySet()+"值:"+map.values()); //删除 Object remove = map.remove("age");//年龄 System.out.println("要删除的数据:"+remove);//打印删除的值 System.out.println("删除后的数据:"+map);//打印删除完之后的数据 System.out.println("键:"+map.keySet()+"值:"+map.values()); //修改 map.put("name", "亚索");//将name的值改为亚索(即为Key覆盖) System.out.println("修改后的数据:"+map); } }
控制台输出结果如下:
那么我们结合之前的list与set集合可以看出它们的主要区别是:
1.List集合:可以存储重复元素,元素的顺序由插入顺序决定,常见的实现类有ArrayList、LinkedList、Vector等。
2.Set集合:不能存储重复元素,元素的顺序无序,常见的实现类有HashSet、TreeSet等。
3.Map集合:存储的是键值对(Key-Value),Key不允许重复,每个Key对应的Value可以重复,元素的顺序无序,常见的实现类有HashMap、TreeMap等。
1.2Key可以为空
在java中,map集合中的key可以为null,例如:
Map<String, Integer> map = new HashMap<>(); map.put(null, 1);
上述代码中,我们将一个null键与对应的值1存储到了Map集合中。那么如果我们再放一个null值在第二个key下,通过之前map.put的演示,毫无疑问第一次存储的null会被第二个null所覆盖。所以在这里我们需要注意的是:当我们使用null作为键时,需要特别小心。因为当Map中同时存在两个null键时,后面的键值对会替换掉前面的键值对,从而导致数据丢失。同时,在使用null键时,我们需要确保能够通过其他途径获得这个键对应的值,否则如果把键从Map中删除后,就无法再获取对应的值了。
2.Map集合的遍历方式
在Java中,List集合、Set集合和Map集合都实现了Collection接口。但是,Map集合并不是继承自Collection接口,而是实现了Map接口。简单来说,List和Set都是Java集合框架中的“集合”,即它们都实现了Collection接口。而Map不同于List和Set,它是一种“映射”结构,实现了Map接口,与Collection接口没有继承关系。因为map不继承collection接口,所以遍历方式不同。
2.1先获取map集合的所有key
代码如下:
package com.Kissship.map; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; /** * Map集合的特点 * 1.键值对的形式存储数据(论证:增删改查) * 2.Key可以为空 * * * @author jj * */ public class Demo1 { public static void main(String[] args) { Map map = new HashMap(); //增加 map.put("name", "李青");//(键值对形式) map.put("age", 22); map.put("sex", "男"); map.put("money", 4800); //因为map不继承collection接口,所以遍历方式不同 //遍历方式一:先获取map集合的所有key Set keySet = map.keySet(); for (Object Key : keySet) { System.out.println("遍历一结果:"+"键:"+Key+";值:"+map.get(Key)); } } }
输出结果如下:
2.2得到map集合的映射关系
在Java中,我们可以通过遍历Map集合的Entry来获取其中的映射关系。Entry是一个Map.Entry<K, V>类型的键值对,它包含了Key和Value两部分,通过遍历Entry我们可以同时获取到Key和Value。
下面是不用泛型的代码,如下:
package com.Kissship.map; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; /** * Map集合的特点 * 1.键值对的形式存储数据(论证:增删改查) * 2.Key可以为空 * * * @author jj * */ public class Demo1 { public static void main(String[] args) { Map map = new HashMap(); //增加 map.put("name", "李青");//(键值对形式) map.put("age", 22); map.put("sex", "男"); map.put("money", 4800); //因为map不继承collection接口,所以遍历方式不同 //遍历方式一:先获取map集合的所有key Set keySet = map.keySet(); for (Object Key : keySet) { System.out.println("遍历一结果:"+"键:"+Key+";值:"+map.get(Key)); } System.out.println("-------------------------"); //遍历方式二:得到map集合的映射的关系 Set entrySet = map.entrySet(); for (Object object : entrySet) { Map.Entry entry = (Entry) object; System.out.println("遍历二结果:"+entry.getKey()+":"+entry.getValue()); } } }
在上述代码中,我们使用Map集合的entrySet()方法获取到Map中所有的键值对,然后使用for循环遍历获取到每一个键值对,通过entry.getKey()获取到Key,通过entry.getValue()获取到Value。
输出结果如下:
需要注意的是,因为Map集合的映射关系是一一对应的,因此在遍历Map集合的Entry时,我们能够保证同时获取到正确的Key和Value。如果只需要遍历Map的Key或Value时,则可以使用Map.keySet()或Map.values()方法进行遍历。
3.Map集合的综合应用
Map集合是Java中非常常用的数据结构,下面结合一个案例来综合应用Map:
案例:随机给任何一个字符串,统计字符串中的字符出现次数。
例如字符串:dawdmaiosnciauvmoikmgopmoihawmdawdpunasicum
考核点:键值对的特点(键不可重复,但是键的值可以覆盖)。
实现的步骤:1.将统计统计字符串中的所有字符获取到。
2.将字符进行遍历。
3.以字符作为map集合的key,在map集合中去找该key对应的值是否存在。
如果存在,key对应的值+1进行key的覆盖。
反之:key对应的值默认为1。
4.遍历map集合。
代码如下:
package com.Kissship.map; import java.util.HashMap; import java.util.Map; /** * 案例:随机给任何一个字符串,统计字符串中的字符出现次数。 * 例如字符串:dawdmaiosnciauvmoikmgopmoihawmdawdpunasicum * @author jj * */ public class Demo2 { public static void main(String[] args) { //1.将统计统计字符串中的所有字符获取到 String str = "dawdmaiosnciauvmoikmgopmoihawmdawdpunasicum"; char[] charArray = str.toCharArray(); //存放字符与出现次数对应关系的map集合容器 Map<Character, Integer> map = new HashMap<Character, Integer>(); System.out.println(charArray); //2.将字符进行遍历 for (char c : charArray) { System.out.println(c); Integer val = map.get(c); //3.以字符作为map集合的key,在map集合中去找该key对应的值是否存在 if (val != null) { //如果存在,key对应的值+1进行key的覆盖 map.put(c, val+1); }else { //反之:key对应的值默认为1 map.put(c, 1); } } //4.遍历map集合 for (Map.Entry<Character, Integer> entry : map.entrySet()) { System.out.println(entry.getKey()+"出现了"+entry.getValue()+"次"); } } }
输出结果如下:
通过对Map集合的综合应用,我们可以有效地实现对数据的管理和统计,并提高程序的运行效率和可维护性。它提供了一种基于Key-Value键值对的数据存储方式,可以便捷地实现数据的查找、修改、删除等操作。在实际开发中,Map集合被广泛应用于数据缓存、数据统计和数据处理等方面。
4.泛型
4.1泛型的作用
4.1.1作用一
作用一:将运行时产生的异常转换为编译期的错误
先看代码(没用泛型):
package com.Kissship.map; import java.util.ArrayList; import java.util.List; /** * 泛型的作用 * @author jj * */ public class Demo3 { public static void main(String[] args) { List list = new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); list.add(6); //获取集合中的奇数 for (Object obj : list) { int num = (int) obj; if (num % 2 == 1) { System.out.println(num); } } } }
输出结果没有任何问题,如下:
接下来我们加一组类型不一样的数据看一下(第一次添加的为单一类型的数据),新增的代码如下:
list.add("a");
然后输出,我们会发现控制台报错,如下:
控制台报错提示字符串不能转换为整数。
接下来我们使用泛型看一下:
Java中的泛型机制可以将一部分运行时异常转化为编译期错误。具体来说,Java泛型机制可以在编译期间检查代码,防止发生因类型转换错误而导致的运行期异常,从而提高程序的可维护性和可靠性。
4.1.2作用二
作用二:提高代码的健壮性
1.泛型的健壮性主要体现在以下几个方面:
- 类型安全
- 可重用性
- 易于编写可读性高的代码
- 提高代码的效率
2.泛型可以指定类、接口和方法,让我们的代码更加健全。
a.泛型类
例:容器类(List.Set.Map集合)
List<String> list = new ArrayList<String>();
例:普通类
public class Demo3<T>
b.泛型接口
public Interface Demo3<T>
c.泛型方法
public <T> add(Goods<T> goods)
总之,使用泛型机制,我们可以在编译期间发现类型转换错误等错误,从而避免因这些错误导致的运行期异常。同时,泛型还能够提高代码的可读性、可维护性和健壮性,使我们更加容易编写出健壮、高效、灵活的程序。
5.集合框架工具类
集合工具类则是对集合框架进行封装的一类工具类,可以使我们更加方便地操作集合数据。
5.1Arrays
Arrays类提供了对数组进行操作的静态方法,例如排序、查找、替换等。
代码如下:
package com.Kissship.map; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; /** * 集合框架工具类的使用 * Arrays,Collections * @author jj * */ @SuppressWarnings("unused")//压制报黄 public class Demo4 { public static void main(String[] args) { int[] intArr = {3,6,1,8,9,2}; System.out.println(Arrays.toString(intArr)); Arrays.sort(intArr);//sort System.out.println(intArr); System.out.println(Arrays.toString(intArr));//toString @SuppressWarnings("unused")//压制报黄 List<int[]> asList = Arrays.asList(intArr);//asList } }
解释:
- sort:按照元素的自然顺序对指定数组按升序进行排序。
- asList(T… a) :将给定数组转换成一个 List。
- toString :将集合转化成字符串,便于我们在调试时查看集合的内容和结构。
控制台输出结果如下:
5.2Collections
Collections类提供了多种对集合进行操作的静态方法,例如排序、查找、替换等。
代码如下:
package com.Kissship.map; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; /** * 集合框架工具类的使用 * Arrays,Collections * @author jj * */ public class Demo4 { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("b"); list.add("a"); list.add("c"); System.out.println(list); Collections.sort(list); System.out.println(list); } }
解释:
- sort:按照元素的自然顺序对指定数组按升序进行排序。
- asList(T… a) :将给定数组转换成一个 List。
- toString :将集合转化成字符串,便于我们在调试时查看集合的内容和结构。
控制台输出结果如下:
最后介绍Map集合的toString方法使用方法:
Map集合的toString方法需要对key-value对进行拼接,并以{}的形式输出,常使用StringJoiner或StringBuffer等类进行字符串拼接处理。例如:
Map<String, Integer> map = new HashMap<>(); map.put("apple", 10); map.put("banana", 20); map.put("pear", 30); StringJoiner joiner = new StringJoiner(", ", "{", "}"); // 构造一个字符串拼接器,指定分隔符为逗号,前后缀为{}。 for (Map.Entry<String, Integer> entry : map.entrySet()) { joiner.add(entry.getKey() + "=" + entry.getValue()); // 拼接每一个key-value对 } String str = joiner.toString(); // 输出 {apple=10, pear=30, banana=20}
以上代码中,我们使用StringJoiner工具类进行字符串拼接,并将最终结果赋值给str。
这些toString方法可以一定程度上简化我们在调试和输出等场景中对集合的处理和展示。同时需要注意的是,这些toString方法的输出格式和顺序都是固定的,不太方便用户自定义。如果需要自定义输出格式,可以使用更加专业的字符串操作库或者手动拼接字符串来实现。
最后J2EE基础(集合框架之Map)就到这里,祝大家在敲代码的路上一路通畅!