南哥带你玩转 Java 之 Java 集合总结
2018-01-25 19:57
344 查看
区别
HashMap 和 Hashtable 的区别
HashMap(JDK1.2) 可以保存 null 值 Hashtable(JDK1.0) 不可以保存 null 值 HashMap 是线程不安全的(效率高) Hashtable 是线程安全的(效率低,耗费资源)
ArrayList、LinkedList 和 Vector 的区别
ArrayList 数组实现,线程不安全 查询快,增删慢 LinkedList 链表实现,线程不安全 查询慢,增删快 Vector 数组实现,线程安全,被 ArrayList 替代了
HashSet、LinkedHashSet 和 TreeSet 的区别
HashSet 哈希算法,线程不安全,作用:去重 LinkedHashSet 线程不安全,特点:有序(怎么存怎么取) TreeSet 线程不安全,作用:排序(两种方法)
HashMap、LinkedHashMap 和 TreeMap 的区别
HashMap 线程不安全,作用:键位可以去重 LinkedHashMap 线程不安全,特点:有序(怎么存怎么取) TreeMap 线程不安全,作用:键位可以排序
Hashtable 线程安全,被 HashMap 取代,不能保存 null 值
例题: /* * 创建联系人类 和 通讯录管理类 使用map和list实现 * 联系人:姓名 年龄 性别 地址 电话 * 通讯录管理类: * 1.添加联系人 * 2.根据分组查找联系人 并针对姓名进行排序 * 例如 传入B分组 查找出 B分组下 姓名首字母是B的所有联系人 * 3.根据电话输出联系人信息 * 4.根据性别查找该性别的所有联系人 并且按照年龄降序排序 * 5.根据姓名删除某个联系人 * 6.删除某个分区的所有联系人 传入B 把姓B的全删了 * 7.修改联系人 */ /* * 联系人:姓名 年龄 性别 地址 电话 */ public class LinkMan { private String name; private Integer age; private String gender; private String address; private String telephone; public LinkMan() { super(); } public LinkMan(String name, Integer age, String gender, String address, String telephone) { super(); this.name = name; this.age = age; this.gender = gender; this.address = address; this.telephone = telephone; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getTelephone() { return telephone; } public void setTelephone(String telephone) { this.telephone = telephone; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((address == null) ? 0 : address.hashCode()); result = prime * result + ((age == null) ? 0 : age.hashCode()); result = prime * result + ((gender == null) ? 0 : gender.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((telephone == null) ? 0 : telephone.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; LinkMan other = (LinkMan) obj; if (address == null) { if (other.address != null) return false; } else if (!address.equals(other.address)) return false; if (age == null) { if (other.age != null) return false; } else if (!age.equals(other.age)) return false; if (gender == null) { if (other.gender != null) return false; } else if (!gender.equals(other.gender)) return false; if (name == null) { if (other.name != null) 4000 return false; } else if (!name.equals(other.name)) return false; if (telephone == null) { if (other.telephone != null) return false; } else if (!telephone.equals(other.telephone)) return false; return true; } @Override public String toString() { return "[姓名 : " + name + ", 年龄 : " + age + ", 性别 : " + gender + ", 地址 : " + address + ", 手机号码 : " + telephone + "]"; } } public class LinkManManager { // 声明一个 TreeMap 保存整个通讯录 private TreeMap<String, ArrayList<LinkMan>> map; // 无参 public LinkManManager() { super(); // 初始化 map map = new TreeMap<>(); } // 只提供 get 方法,不希望外界修改通讯录,不提供 set 方法 public TreeMap<String, ArrayList<LinkMan>> getMap() { return map; } // 遍历 map public void printMap() { System.out.println("****************************"); for (String key : map.keySet()) { System.out.println(key + "组联系人 : "); // 通过 key 找对应的 value,value 是个数组 ArrayList<LinkMan> list = map.get(key); // 遍历每一个 list for (LinkMan linkMan : list) { System.out.println(linkMan); } } System.out.println("****************************"); } // 遍历 arraylist 方法 public void printList(ArrayList<LinkMan> arrayList) { for (LinkMan linkMan : arrayList) { System.out.println(linkMan); } } // 添加联系人 /* * 分区不存在 * 创建一个数组,将联系人放入数组中 * 把联系人和对应的 key 放进 map 中 * * 分区存在 * 直接利用大写首字母即分区的名字( key )取出对应的数组 * 把联系人存进数组中 */ public void addLinkMan(LinkMan linkMan) { // 防御式判断 if (linkMan == null || linkMan.getName().isEmpty()) { System.out.println("联系人信息为空,请重新输入!"); // 直接结束方法 return; } // 取出名字的大写首字母 String key = Pinyin4jUtil.getFirstLetter(linkMan.getName()); // 判断这个 key 是否存在于 map 中 if (!map.containsKey(key)) { // 不存在 // 创建数组 ArrayList<LinkMan> list = new ArrayList<>(); list.add(linkMan); System.out.println("已成功添加联系人:" + linkMan.getName()); // 把数组和 key 放进 map 中 map.put(key, list); } else { // 键值对存在于 map 中 // 用 key 把对应数组取出来 ArrayList<LinkMan> arrayList = map.get(key); // 把人放进去(去重) if (!arrayList.contains(linkMan)) { // 数组中不包含此联系人 // 把联系人放入 value 中 System.out.println("已成功添加联系人:" + linkMan.getName()); arrayList.add(linkMan); } else { System.out.println("已存在" + linkMan.getName() + "这个联系人,请勿重复添加!"); } /* * 注意:这里不需要进行重新覆盖,因为 arraylist 不是重新 new 出来的 * 保存的就是 map 中的数组的地址 * 操作的是同一个空间,所以,不用再重新把之前的 value 覆盖 * 不需要执行 map.put(key, arrayList); * 可写可不写,写出来看的明了,多一步操作,不写需要梳理一下思路 */ // 把 value 重新覆盖之前的 value // map.put(key, arrayList); } } // 根据分组查找联系人,并针对姓名进行排序 /* * 1.没这个分组 * 2.有这个分组 */ public void findLinkMansByGroup(String group) { // 把分组转成大写(避免传入是小写) String upperGroup = group.toUpperCase(); // 根据分组找对应的数组 if (!map.containsKey(upperGroup)) { // 没有这个分组 System.out.println("没有" + upperGroup + "这个分组!"); return; } // 有分组,利用 TreeSet 排序,操作原 arraylist ArrayList<LinkMan> arrayList = map.get(upperGroup); // 创建 TreeSet TreeSet<LinkMan> set = new TreeSet<>(new SortByNameImpl()); set.addAll(arrayList); arrayList.clear(); arrayList.addAll(set); // 打印 printList(arrayList); } // 根据电话输出联系人信息 /* * 遍历 map 寻找联系人 * 1.没找到 * 2.找到了输出联系人信息 */ public void findLinkManByPhone(String telephone) { // 判断一下电话号码是否为空 if (telephone.isEmpty() || telephone == null) { System.out.println("输入号码为空!"); return; } // 记录法 // 定义一个空的引用,来记录找到的联系人 LinkMan linkMan = null; for (String key : map.keySet()) { // 找出对应 list ArrayList<LinkMan> arrayList = map.get(key); // 遍历数组,找到号码相同的 for (LinkMan linkMan2 : arrayList) { // 找号码相同的 if (telephone.equals(linkMan2.getTelephone())) { // 记录这个联系人 linkMan = linkMan2; } } } // 判断有无这个联系人,有就输出联系人信息,没有进行提示 if (linkMan == null) { System.out.println("查无此号,请确认号码是否输入正确!"); } else { System.out.println(linkMan); } } // 根据性别查找该性别的所有联系人,并且按照年龄降序排序 public void findLinkMansByGender(String gender) { // 判断传的字符串是否为男/女 if (!(gender.equals("男") || gender.equals("女"))) { // 输入性别不是男/女 System.out.println("不存在" + gender + "这个性别,无法查询!"); return; } // 创建一个容器,保存多个联系人 ArrayList<LinkMan> genderList = new ArrayList<>(); // 遍历集合 for (String key : map.keySet()) { ArrayList<LinkMan> list = map.get(key); // 遍历集合 for (LinkMan linkMan : list) { // 判断性别相同,添加到新数组中 if (gender.equals(linkMan.getGender())) { // 添加到新数组中 genderList.add(linkMan); } } } // 判断数组中是否有人 if (genderList.isEmpty()) { System.out.println("分组中无" + gender + "性联系人"); return; } TreeSet<LinkMan> set = new TreeSet<>(new SortByAgeImpl()); set.addAll(genderList); genderList.clear(); genderList.addAll(set); printList(genderList); } // 根据姓名删除某个联系人 /* * 1.无该名字的联系人 * 提示不存在此联系人 * * 2.有该名字的联系人 * ①.删除该联系人之后,没有其他人,需要把分区一起删了 * ②.删除该联系人之后,还有其他人,不用管他 */ public void removeLinkManByName(String name) { // 判读用户名是否为空 if (name == null) { System.out.println("输入用户名为空,无法删除!"); return; } // 取出首字母 String firstLetter = Pinyin4jUtil.getFirstLetter(name); // 判断有没有该名字分区 if (!map.containsKey(firstLetter)) { System.out.println("没有" + firstLetter + "这个分区,无此联系人,无法删除!"); return; } // 记录要删除的联系人 LinkMan removeMan = null; // 记录删除的人所在的数组 ArrayList<LinkMan> removeList = null; // 遍历,寻找名字相同的联系人 for (String key : map.keySet()) { ArrayList<LinkMan> list = map.get(key); for (LinkMan linkMan : list) { // 名字相同 if (name.equals(linkMan.getName())) { // 记录要删除的人 removeMan = linkMan; // 记录人所在的数组 removeList = list; } } } // 判断一下有没有这个人 if (removeMan == null) { System.out.println("该分区无" + name + "这个联系人,无法删除!"); return; } // 把这个人删除 removeList.remove(removeMan); // 判断数组是否为空 if (removeList.isEmpty()) { // 直接删除分区 removeLinkMansByGroup(firstLetter); return; } printMap(); } // 删除某个分区的所有联系人(传入 A, 把姓名大写首字母为 A 的联系人全部删除) public void removeLinkMansByGroup(String group) { // 转大写 String upperGroup = group.toUpperCase(); // 判断有无该分区,有就删,没有就提示 if (!map.containsKey(upperGroup)) { System.out.println(upperGroup + "分区不存在,无法删除!"); return; } // 有,直接删除 map.remove(upperGroup); // 打印 printMap(); } // 修改联系人姓名 /* * 1.有老名字的分区 * ①.有这个老名字 * (1).改名没改姓的大写首字母 * 找到这个人,调用 set 方法,直接修改姓名(不需要改分区) * (2).改名改姓的大写首字母 * a.利用老的联系人创建一个新的联系人 * b.删除老的联系人 * 1)看一下数组中,是否还存在其他人(有就留着分区,没有就将分区删除) * c.直接调用添加方法把新人添加进去 * * ②.没有这个老名字 * 提示查无此人,无法修改 * * 2.没有老名字的分区 * 提示无该分区,无法修改 */ public void setLinkManByOldNameAndNewName(String oldName, String newName) { // 将新旧名字的大写首字母 String oldKey = Pinyin4jUtil.getFirstLetter(oldName); String newKey = Pinyin4jUtil.getFirstLetter(newName); // 查看有没有老名字的分区 if (!map.containsKey(oldKey)) { // 没有老名字分区 System.out.println("无" + oldKey + "这个分区,无法修改!"); return; } // 有老名字分区(查看有没有老名字的联系人) ArrayList<LinkMan> oldList = map.get(oldKey); // 创建一个引用保存这个人 LinkMan oldMan = null; //遍历集合 for (LinkMan linkMan : oldList) { // 对比名字 if (oldName.equals(linkMan.getName())) { // 名字相同,记录此人 oldMan = linkMan; } } // 判断有没有这个老名字的联系人 if (oldMan == null) { System.out.println("没有查询到叫" + oldName + "的联系人,无法修改!"); return; } // 有这个老名字的联系人(判断改没改名字大写首字母) if (oldKey.equals(newKey)) { // 名字大写首字母相等 // 直接修改名字 oldMan.setName(newName); } else { // 名字大写首字母不相等 // 利用新名字创建新对象 LinkMan newLinkMan = new LinkMan(newName, oldMan.getAge(), oldMan.getGender(), oldMan.getAddress(), oldMan.getTelephone()); // 删除老名字的联系人 removeLinkManByName(oldName); // 把新名字的联系人添加 addLinkMan(newLinkMan); } } } // 按姓名排序 class SortByNameImpl implements Comparator<LinkMan>{ @Override public int compare(LinkMan o1, LinkMan o2) { int num = o1.getName().compareTo(o2.getName()); return num == 0 ? 1 : num; } } // 按年龄降序 class SortByAgeImpl implements Comparator<LinkMan>{ @Override public int compare(LinkMan o1, LinkMan o2) { int num = o2.getAge() - o1.getAge(); return num == 0 ? 1 : num; } } /* * 测试类 */ public class Test { public static void main(String[] args) { LinkManManager manager = new LinkManManager(); manager.addLinkMan(new LinkMan("张1", 40, "男", "九干路168号", "13811554605")); manager.addLinkMan(new LinkMan("张3", 19, "男", "九干路168号", "13811554607")); manager.addLinkMan(new LinkMan("张4", 30, "男", "九干路168号", "13811554608")); manager.addLinkMan(new LinkMan("张2", 18, "男", "九干路168号", "13811554606")); manager.addLinkMan(new LinkMan("张5", 15, "女", "九干路168号", "13811554605")); manager.addLinkMan(new LinkMan("李2", 18, "女", "九干路168号", "13811554606")); manager.addLinkMan(new LinkMan("谢5", 15, "女", "九干路168号", "13811554605")); manager.addLinkMan(new LinkMan("谢6", 15, "女", "九干路168号", "13811554605")); manager.printMap(); } }
http://blog.csdn.net/huzongnan/article/list
相关文章推荐
- 南哥带你玩转 Java 之 Java 集合--set
- 南哥带你玩转 Java 之 Java 集合--list
- 南哥带你玩转 Java 之 Java 集合应用 -- DVD管理
- 南哥带你玩转 Java 之 Java 集合(泛型及集合删除方法)
- Java基础-17总结,登录注册案例,Set集合,HashSet,TreeSet,LinkHashSet
- Java集合之List遍历找到匹配元素删除方法总结
- java集合总结
- java学习总结(16.07.18-16.07.21)集合与泛型
- java_集合体系之List体系总结、应用场景——07
- Java中各种集合及其特点功能总结
- Java集合和数组的排序方式总结
- Java 集合系列之 List总结(LinkedList, ArrayLis,vector,stack等使用场景和性能分析)
- Java 集合总结(Collection系列与Map系列)
- java中的集合List,Set,Map小总结
- Java通用集合工具总结
- java_集合的遍历总结
- java集合总结
- java集合~List体系总结、ArrayList分析
- JAVA 面向对象和集合知识点总结
- java集合Map,HashMap,TreeMap知识点总结