Java 之 Java 集合总结

区别

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)
				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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值