黑马程序员——【学习笔记】集合——Map、HashMap、TreeMap

本文介绍了Java集合框架中的Map接口及其常见实现类,包括HashTable、Properties、HashMap和TreeMap。重点讲解了Map的特性、常用方法及遍历方式,并探讨了如何自定义HashMap排序和使用LinkedHashMap保持插入顺序。此外,还提及了Collections工具类的排序、查找和替换等实用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


------- android培训 java培训 、期待与您交流!----------



1 Map

Map的常用子类:

——HashTable:内部结构是哈希表,是同步的。不允许null作为键或值。无序。

——Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。

——HashMap:内部结构是哈希表,不是同步的 。允许null作为键或值。无序。

——TreeMap:内部结构是二叉树,不是同步的。可以对Map集合中的键进行排序。无序。

PS:HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持。


1.1 Map:一次添加一对元素(即键值对——键:值),而Collection是一次添加一个元素。Map集合也称为双列集合,Collection集合称为单列集合。


1.2 Map保证元素唯一的方法:就是保证键的唯一性。就算同一个键对应两个不同的值,也算作重复元素。因为Map是通过键来索取值的。


1.2 Map常用方法

增——添加

value put(key,value);如果有这个key的话,就返回key关联的值,然后用新的键值把它替代掉,如果没有就返回nul,然后加入新键值


删——删除

void clear();清空map集合;

value remove(Object key);删除指定的key对应的键值对,并提取该值。


判断

boolean containsKey(key);判断是否含有指定key

boolean containsValue(value);判断是否含有指定的值;

boolean isEmpty();判断集合是否为空


查——获取

value get(key);根据指定的 键获取值,如果没有该值就返回null。可以通过返回null来判断是否包含指定键。

int size();获取键值对个数。

Collection value();获取该集合的值,作为Collection集合返回。

Set keySet();返回此集合中的键,作为Set集合

Set entrySet();返回此集合中的映射关系,作为Set集合

package demo;

import java.util.HashMap;
import java.util.Map;

public class Day18 {
	public static void main(String[] args){
		Map m = new HashMap();
		System.out.println(m.put("male", "zhangsan"));
		System.out.println(m.put("female","lisi"));
		System.out.println(m.put("male","lisi"));
		System.out.println(m.put("male","wangwu"));
		System.out.println(m);
		m.put(8, "八");
		m.put(9, "九");
		System.out.println(m.remove("male"));
		System.out.println(m.containsKey(8));
		System.out.println(m.containsValue("zhangsan"));
		System.out.println(m.get("male"));
	}
}
但是HashMap没有根据值获取键的方法,因为一个值可能有几个键。


1.3 Map的取出

Map没有迭代器,所以如果要遍历它,要用以下三种方法:

①需要先用keySet把键取出来,并用Set存储,再遍历Set集合,途中通过get(key)方法将每个键对应的值取出。

②使用entrySet()方法将map集合转成set集合(把映射关系(Map.Entry<>)存入Set),再通过迭代器取出。

Map.Entry<>是一个Map的一个内部接口,存储一对键值,即映射关系。这样,Set里的每个元素都是Map.Entry的一个实例对象。用getKey()和getValue()可得到键和值。同时也有setKey() setValue()

③直接用value()方法将值返回到一个Collection的子类集合中,然后遍历。

public class Day18{
	public static void main(String[] args){
		Map m = new HashMap();
		m.put("zhangsan", 12);
		m.put("lisi", 13);
		m.put("wangwu", 15);
		m.put("zhaoliu", 15);
		System.out.println(m);
	
		Set s = m.keySet();
		System.out.println(s);
		Iterator i = s.iterator();
		while(i.hasNext()){
			String str = (String) i.next();
//			System.out.println(str);
			int x = (Integer) m.get(str);
			System.out.println(x);}
		System.out.println("------------");
		Set s1 = m.entrySet();
		System.out.println(s1);
		Iterator i1 = s1.iterator();
		while(i1.hasNext()){
//			System.out.println(i1.next().getClass());
//			String me = (String) i1.next();
//			System.out.println(me);
			Map.Entry me = (Map.Entry)i1.next();
			System.out.println(me.getKey()+"=="+me.getValue());
		}
		System.out.println("------------");
		Collection coll = m.values();
		Iterator i2 = coll.iterator();
		while(i2.hasNext()){
			System.out.println(i2.next());
		}
	}
}<span style="color:#ff0000;font-weight: bold;">
</span>

{lisi=13, zhaoliu=15, zhangsan=12, wangwu=15}
[lisi, zhaoliu, zhangsan, wangwu]
13
15
12
15
------------
[lisi=13, zhaoliu=15, zhangsan=12, wangwu=15]
lisi==13
zhaoliu==15
zhangsan==12
wangwu==15
------------
13
15
12
15


1.4 自定义HashMap排序

HashMap是按照HashCode和equals来排序而不是按照输入顺序。往往不是我们想要的排序方式。这时可以覆盖它的HashCode和equals,相当于创建了自己定义的“相同键判断方式”和“排序方式”了。

class Student{
	private String name;
	private int age;
	Student(String name,int age){
		this.name=name;
		this.age=age;
	}
	void setName(String name){
		this.name=name;
	}
	String getName(){
		return name;
	}
	void setAge(int age){
		this.age=age;
	}
	int getAge(){
		return age;
	}
	public int hashCode(){
		final int prime = 31;
		int result=1;
		result=prime*result+age;
		result=prime*result+((name==null)?0:name.hashCode());
		return result;
	}
	public boolean equals(Object obj){
		if(this==obj)
			return true;
		if(obj==null)
			return false;
		if(getClass()!=obj.getClass())
			return false;
		Student s = (Student)obj;
		if(age!=s.age){
			return false;
		}
		if(name==null){
			if(s.name!=null)
				return false;
		}else if (!name.equals(s.name))
			return false;
		return true;
	}
}
public class Day18{
	public static void main(String[] args){
		HashMap<Student,String> hm = new HashMap<Student,String>();
		hm.put(new Student("zhangsan",10),"beijing");
		hm.put(new Student("lisi",13),"shanghai");
		hm.put(new Student("wangwu",11),"guagnzhou");
		hm.put(new Student("zhaoliu",14),"shenzhen");
		hm.put(new Student("liuqi",12),"chegndu");
		hm.put(new Student("zhaoliu",14),"shenzhen");
		hm.put(new Student("zhaoliu",14),"nanjing");
		Iterator<Student> i = hm.keySet().iterator();
		while(i.hasNext()){
			Student key = i.next();
			String city = hm.get(key);
			System.out.println(key.getName()+"...."+key.getAge()+"..."+city);
		}
	}
}
zhaoliu....14...nanjing
lisi....13...shanghai
liuqi....12...chegndu
zhangsan....10...beijing
wangwu....11...guagnzhou
PS:当键相同,后加入的元素会覆盖之前的元素。


1.5 LinkedHashMap

如果希望输入的键值对集合按照跟原来存入的顺序一致,就使用LInkedHashMap。

public class Day18{
	public static void main(String[] args){
		LinkedHashMap<String,String> lhm = new LinkedHashMap<String,String>();
		lhm.put("zhangsan", "male");
		lhm.put("lisi", "male");
		lhm.put("wangwu", "female");
		lhm.put("zhaoliu", "male");
		lhm.put("liuqi", "female");
		System.out.println(lhm);
		Set<String> s = lhm.keySet();
		Iterator i = s.iterator();
		while(i.hasNext()){
			System.out.println(i.next().hashCode());
		}
	}
}
{zhangsan=male, lisi=male, wangwu=female, zhaoliu=male, liuqi=female}
-1432604556
3322003
-795136991
-323273412
102984368
虽然LinkedHashMap能以输以顺序排序,但是它并没有在键的HashCode上做处理。


2 Collections工具

Collections:是集合框架的工具类,专门用于操作集合,里面的方法都是静态的。为集合提供了方便的方法。比如:要不考虑唯一性地存放一组对象,要用List接口,但是想要对该集合做排序的话,又不能用Tree的比较器。这是就可以用Collections里的sort()方法。不能给Set排序


2.1 排序

<T  extends Comparable<? super T>> sort(List<> list);根据元素的自然顺序对指定列表按升序进行排序。

sort方法可以传入比较器sort(List<T> list, Comparator<? super T comp> 

public class Day19 {
	public static void main(String[] args){
		sortDemo();
	}
	public static void sortDemo(){
		List<String> list = new ArrayList<String>();
		list.add("abcd");
		list.add("bbb");
		list.add("ddea");
		list.add("bdfd");
		list.add("bb");
		System.out.println(list);
//		Collections.sort(list);//默认是自然顺序
//		System.out.println(list);
		Collections.sort(list,new StrLenCom());
		System.out.println(list);
	}
}
class StrLenCom implements Comparator<String>{
	public int compare(String s1, String s2){
		if(s1.length()>s2.length())
		?	return 1;
		if (s2.length()<s2.length())
			return -1;
		return s1.compareTo(s2);
//		return 0;
	}
}


2.2 求最大

Object Collections.Max(List list);求集合只能个自然排序的最大值

Object Collections.Max(List list, Comparator comp);求集合中的最大元素

2.3 二分法查找

二分法查找必须使元素具备可比性(即元素extends Comparable)或者方法里输入了比较器(即xxx implements Comparator)

<T> int Collections.binarySearch(List<? extend Comparable<? super T>> list, T key)

<T> int Collections.binarySearch(List<? extend T> list, T key, Comparator<? super T>)


2.4 替换

Collections.fill(List<? super T> list,Object obj);将集合中所有元素替换成指定元素

Collections.replacaAll(List<T> list,T oldVal, T newVal);j将集合中所有old元素替换成new元素


2.5 翻转

Collections.reverse(List<?> list)翻转指定列表中元素的顺序


2.6 洗牌

Collections.shuffle(List<T> list);将指定集合中的元素洗牌。


2.7 同步

因为集合框架中常用的集合类都是不同步的,一旦被多线程运用,就很容易出现安全问题。

比如添加元素,一次只能一个线程添加,否则会混乱。

Collection Collections.synchronizedCollection(Colleciton c);返回同步的Collection集合。

synchronizedList

synchronizedSet

...


3 Arrays

Arrays:用于操作数组的工具类

里面都是静态方法。

Arrays.asList():将数组变成List集合

把数组变成List集合的好处:可以使用集合的思想和方法来操作 数组中的元素。

class Day19{
	public static void main(String[] args){
		int[] i = {1,2,3,4,2,1};
		String[] s = {"xxx","dfdf","kkk"};
		List<String> l = Arrays.asList(s);
		System.out.println(l);
		System.out.println(l.contains("xxx"));
	}
}
但是通过asList得来的集合不可以使用集合的增删方法。因为数组的长度是固定的。

可以使用

contains

get

indexOf

subList

...都可以

如果增删了,会发生不支持操作异常


class Day19{
	public static void main(String[] args){
		int[] i = {1,2,3,4,2,1};
		String[] s = {"xxx","dfdf","kkk"};
		List<String> l = Arrays.asList(s);
		System.out.println(l);
		System.out.println(l.contains("xxx"));
		int[] nums = {1,2,4,3};
//		List<Integer> l1 = Arrays.asList(nums);//cannot convert from List<int[]> to List<Integer>
		List<int[]> l1 = Arrays.asList(nums);
		System.out.println(l1);
		Integer[] nums1 = {1,2,4,3};
		List<Integer> l2 = Arrays.asList(nums1);
		System.out.println(l2);
		}
	}
[xxx, dfdf, kkk]
true
[[I@659e0bfd]
[1, 2, 4, 3]


注意:如果是数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素。

如果数组中的元素都是基本数据类型,那么会将数组本体作为集合中的元素导入。

因为int[]只能作为"int[]"类型对象来装入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值