一、Map集合数据结构
1.1 Map的特点
- 键值对存储:Map集合存储的数据以键值对的形式出现,每个键唯一对应一个值。
- key无序且唯一:Map集合中的键无序,并且每个键只能出现一次,如果重复则会覆盖之前的值。
- 支持快速查找:由于Map集合内部实现了哈希表,所以可以在很短的时间内查找到指定键对应的值。
- 可以存储不同类型的数据:Map集合中可以存储任意类型的键和值,例如字符串、数字、对象等等。
- 可以动态地增加和删除元素:Map集合允许动态地增加和删除元素,可以在任何时候添加新的键值对或者删除已有的键值对。
- 没有继承Collection接口
1.2 Map集合的使用及遍历
1.2.1 Map集合常用的方法 :
put (key,value) | 把指定的键与指定的值添加到Map集合中 |
remove(Object key) | 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值 |
get (Object key) | 根据指定的键,在Map集合中获取对应的值 |
containKey (Object key) | 判断该集合中是否有此键。 |
containValue (Object value) | 判断该集合中是否有此值。 |
接下来就是代码演练 :
1. put方法
package com.ycxw.map; import java.util.HashMap; import java.util.Map; /** * * @author 云村小威 * */ public class Text_01 { public static void main(String[] args) { //创建Map集合 Map maps = new HashMap<>(); //添加内容到集合 put方法 maps.put("a", 10); maps.put("b", 11); maps.put("c", 12); maps.put("d", 13); System.out.println(maps); //运行结果: //{a=10, b=11, c=12, d=13} } }
2. remove
Object remove = maps.remove("a"); System.out.println("返回删除的值"+remove); System.out.println(maps);
3. get方法
Object object = maps.get("a"); System.out.println(object); //运行结果: 10
4. containKey方法
boolean one = maps.containsKey("a"); boolean two = maps.containsKey("e"); System.out.println(one); //返回true System.out.println(two); //返回false
5. containValue方法
boolean one = maps.containsValue(10); boolean two = maps.containsValue(21); System.out.println(one); //返回true System.out.println(two); //返回false
1.2.2 Map使用foreach遍历
要先获取去所有的key,遍历key然后通过key获取每一个key和value,代码和结果如下:
package com.ycxw.map; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * Map集合遍历第一种方式 * * @author 云村小威 * */ public class Text_02 { public static void main(String[] args) { // 创建Map集合 Map maps = new HashMap<>(); // 添加内容到集合 put方法 maps.put("a", 10); maps.put("b", 11); maps.put("c", 12); maps.put("d", 13); // 获取key值 Set keySet = maps.keySet(); //通过foreach遍历set集合 for (Object object : keySet) { // 根据key获取值 Object object2 = maps.get(object); System.out.println("key为:"+object+"--value"+object2); } } }
1.2.3 通过entrySet方法进行遍历
先通过调用entrySet方法遍历集合,集合中元素的类型是Map.Entry,取出Map.entry对象之后,可以获取到key和value,代码和结果如下:
package com.ycxw.map; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * Map集合遍历第二种方式 * * @author 云村小威 * */ public class Text_03 { public static void main(String[] args) { // 创建Map集合 Map maps = new HashMap<>(); // 添加内容到集合 put方法 maps.put("a", 10); maps.put("b", 11); maps.put("c", 12); maps.put("d", 13); for (Object o : maps.entrySet()) { Map.Entry entry = (Map.Entry) o; System.out.println("key为" + entry.getKey() + " -- value为" + entry.getValue()); } } }
1.3 通过HashMap实现统计字符串出现的次数案例
package com.ycxw.map; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * 通过hashMap实现统计字符串出现的次数案例 * * @author 云村小威 * */ public class Text_04 { public static void main(String[] args) { // 定义一个字符串 String str = "asdfghjklzxcvbnmqwertyuiosdfghjhgfdsxcvbnmgfdf"; // 转成字符串数组 char[] array = str.toCharArray(); // 创建hashMap集合 Map maps = new HashMap<>(); // 遍历字符串数组 for (char c : array) { // 首先根据每一个key获取value值 Object o = maps.get(c); // 判断如果没有此key就进行添加 if (o == null) { maps.put(c, 1); } else { // Integer.valueOf('') 返回的是字符串中隐含数字的对应十进制整数 maps.put(c, Integer.valueOf(o.toString()) + 1); } } for (Map.Entry entry : (Set<Map.Entry>) maps.entrySet()) { System.out.println(entry.getKey() + "出现了" + entry.getValue() + "次"); } //运行结果: a出现了1次 b出现了2次 c出现了2次 d出现了4次 e出现了1次 f出现了5次 g出现了4次 h出现了3次 i出现了1次 j出现了2次 k出现了1次 l出现了1次 m出现了2次 n出现了2次 o出现了1次 q出现了1次 r出现了1次 s出现了3次 t出现了1次 u出现了1次 v出现了2次 w出现了1次 x出现了2次 y出现了1次 z出现了1次 } }
1.4 TreeMap
它是一个有序的集合,可以任意顺序将元素插入到集合中,对集合进行遍历的时候每个元素将自动按照排好序的顺序输出。他的底层是采用了二叉树对元素进行排序。
TreeSet里面绝大部分方法都市直接调用TreeMap方法来实现的。
不同的是:
- 最主要的区别就是TreeSet和TreeMap分别实现Set和Map接口
- TreeSet只存储一个对象,而TreeMap存储两个对象Key和Value(仅仅key对象有序)
- TreeSet中不能有重复对象,而TreeMap中可以存在
TreeSet集合用法详情 请点击跳转
二、 泛型
泛型指定了键和值的类型,使得在编译时就能进行类型检查,避免了在运行时出现类型错误的情况。
2.1 作用:提高代码的健壮性
2.1.1 实例:不健壮的代码:
package com.ycxw.map; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * 泛型的作用 * 1. 不健壮代码是编译不报错,运行报错 * @author 云村小威 * */ public class Text_05 { public static void main(String[] args) { // 创建Map集合 Map maps = new HashMap<>(); // 添加内容到集合 put方法 maps.put(1, 10); maps.put(2, 11); maps.put(3, 12); maps.put(4, 13); maps.put("a", 14); Set keySet = maps.keySet(); for (Object o : keySet) { if (Integer.valueOf(o.toString()) % 2 == 0) { System.out.println(o); } } } }
运行结果:
Exception in thread "main" java.lang.NumberFormatException: For input string: "a"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.valueOf(Integer.java:766)
at com.ycxw.map.Text_05.main(Text_05.java:26)
2.1.2 健壮的代码(通过设置泛型)
会出现报错;
2.2 扩展:泛型类及泛型方法的使用
package com.ycxw.map; import java.util.HashMap; import java.util.Map; /** * 泛型类及泛型方法的使用 * * @author 云村小威 * */ public class Text_06 { public static void main(String[] args) { //测试 Dao<Person> dao = new Dao<Person>(); // 对map进行实例化,任何对象在使用的时候都需要初始化, //前面我们没有给map赋值,这里不初始化直接使用的话会报空指针异常 dao.maps = new HashMap<Object,Person>(); //调用添加元素方法 dao.put("a", new Person(1, "小黑子", 18)); dao.put("b", new Person(2, "ikun", 21)); System.out.print(dao.maps); } } // 定义一个实体类 class Person { private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Person(int id, String name, int age) { super(); this.id = id; this.name = name; this.age = age; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", age=" + age + "]"; } } // 泛型类 class Dao<T> { // 创建一个map集合 Map<Object, T> maps; // 定义一个泛型添加集合方法 public void put(Object o, T entity) { maps.put(o, entity); } }
三、 集合框架工具类
Collections类和Arrays类都是JAVA提供的一个集合操作工具类,其包含的方法都是静态方法,为什么是静态的方法,就是可以通过类名直接调用,不需要进行实例化对象,方便引用。
3.1 Arrays类使用
Arrays类中的方法方便对数组进行排序,查找,替换等一系列操作
package com.ycxw.map; import java.util.Arrays; /** * 集合工具Arrays类的使用 * * @author 云村小威 * */ public class Text_07 { public static void main(String[] args) { // 定义一个数组 int[] arr = { 3, 12, 35, 5, 7 }; // 调用sort升序 Arrays.sort(arr); // Arrays.toString 转换成字符串 System.out.println(Arrays.toString(arr)); // 因为Arrays里面没有反转元素的顺序,要想从小到大;可以利用for循环进行; for (int i = arr.length - 1; i > 0; i--) { System.out.println(arr[i]); } } }
3.2 Collections工具类使用
Collections,该工具类提供了大量方法对集合进行排序、查询和修改等操作,还提供了将集合对象置为不可变、对集合对象实现同步控制等方法。
这个类不需要创建对象,内部提供的都是静态方法。
3.2.1排序操作
方法:
- static void reverse(List list): 反转列表中元素的顺序。
- static void shuffle(List list) : 对List集合元素进行随机排序。
- static void sort(List list) 根据元素的自然顺序 对指定列表按升序进行排序
- static void sort(List list, Comparator c) : 根据指定比较器产生的顺序对指定列表进行排序。
- static void swap(List list, int i, int j) 在指定List的指定位置i,j处交换元素。
- static void rotate(List list, int distance) 当distance为正数时,将List集合的后distance个元素“整体”移到前面;当distance为 负数时,将list集合的前distance个元素“整体”移到后边。该方法不会改变集合的长度。
package com.ycxw.map; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * 集合工具Collections类的使用 * * @author 云村小威 * */ public class Text_08 { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add(3); list.add(2); list.add(9); list.add(5); list.add(6); list.add(8); // 输出:[3, 2, 9, 5, 6, 8] System.out.println(list); // 集合元素的次序反转 Collections.reverse(list); // 输出:[8, 6, 5, 9, 2, 3] System.out.println(list); // 排序:按照升序排序 Collections.sort(list); // [2, 3, 5, 6, 8, 9] System.out.println(list); // 根据下标进行交换 Collections.swap(list, 2, 5); // 输出:[2, 3, 9, 6, 8, 5] System.out.println(list); // 随机排序 Collections.shuffle(list); // 每次输出的次序不固定 System.out.println(list); // 后两个整体移动到前边 Collections.rotate(list, 2); // 输出:6, 3, 5, 9, 8, 2] System.out.println(list); } }