Map接口与其子接口及子接口的实现类;

本文详细介绍了Map接口及其常用实现类,包括HashMap、LinkedHashMap和TreeMap。HashMap实现了快速存取,LinkedHashMap保持插入顺序,而TreeMap则根据key进行排序。此外,还探讨了HashTable及其子类Properties的使用,特别是在处理属性文件中的键值对。文章提供了丰富的代码示例,展示了如何遍历Map、使用LinkedHashMap、TreeMap以及Properties处理属性文件的方法。

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

                                                 Map接口

前情概要:

存放Set集合元素的容器,必须要重写hashCode( )和equals( )方法,这样才可以保证Set集合中的元素不会重复。

凡是跟集合这块,要你存的话,equals( )方法是一定要写的;如果是跟Map或Set相关的话,除了写equals( )方法外,还要写hashCode( )方法。

上图中实线表示继承;虚线表示实现。

一个ksy-value对就是一个entry;所有的entry是一个set。

一、Map常用的集合元素:

 

1、Map集合的实现定义与在Map集合中的添加、删除操作:

package com.atguigu.Map00;

import java.util.HashMap;

import java.util.Map;



/*

 * Collection接口

 *

 * Map接口

 *                 |------HashMap:Map的主要实现类

 *                 |------LinkedHashMap:

 *                 |------TreeMap:

 *                 |------HashTable

 *                        |------Properties

 * */

import org.junit.Test;

/*

 * HashMap:

 * 1、key是用Set来存放的,不可重复。value是用Collection来存放的,可重复;

 *一个key-value对,是一个Entry。所有的Entry是用Set存放的,也是不可重复的。

 * 2、向HashMap中添加元素时,会调用key所在类的equals()方法,判断两个key是否相同。

 * 若相同则只能添加进后添加的那个元素。

 * */

public class TestMap {

       @Test

       public void testMap1() {

              Map map=new HashMap();    //1、Object put(Object key,Object value):向Map中添加一个元素

//          map.put(key, value);

              map.put("AA", 213);       //正是因为key是不可重复的所有Entry才不可重复。

              map.put("BB", 456);

              map.put("BB", 456);

              map.put(123, "CC");

              map.put(null, null);

              map.put(new Person("DD",23), 89);//put的两个Person实体类对象添加成功一个,因为key值不能相等。

              map.put(new Person("DD",23), 98);

              System.out.println(map.size());//结果为:4(因为put()里添加了一个key值重复的,只能算一个。)

              System.out.println(map);

/*

 * 结果:

5

{AA=213, BB=456, null=null, 123=CC, com.atguigu.Map00.Person@14c8c=98}

*/

              map.remove("AA");

              System.out.println(map.size());

              System.out.println(map);

//          map.clear();     //clear:清空Map集合

              System.out.println(map.get(123));//get:输出key值为123对应的value值;如果没有此key则返回null。

       }

}

2、元视图操作的方法:

//遍历Map集合中的key值用某某.keySet()”

//遍历Map集合中的value值用某某.values()”

//遍历Map集合中的key-value对用某某.entrySet()”

Map map=new HashMap();

//1、遍历key(".keySet"):输出的结果与添加进HashMap的顺序不同。

        Set set=map.keySet();

        for(Object obj:set) {

            System.out.println(obj);

        }

//2、遍历value:".values"

        Collection values=map.values();

        Iterator i=values.iterator();

        while(i.hasNext()) {

            System.out.println(i.next());

        }

//3、如何遍历key-value

//      方式一:

        Set set1=map.keySet();

        for(Object obj:set1) {//通过key找相应的value

            System.out.println(obj+"------>"+map.get(obj));

        }

//      方式二:

        Set set2=map.entrySet();

        for(Object obj:set2) {

            Map.Entry entry=(Map.Entry)obj;//创建一个Map.Entry类型的。

//          System.out.println(entry.getKey()+"------>"+entry.getValue());

            System.out.println(entry);

        }

 

①、代码例题演示:

public class TestMap {

    /*

     * 如何遍历Map

     * Set keySet()

     * Collection values()

     * Set entrySet()

     * */

    @Test

    public void testMap2() {

        Map map=new HashMap();

        map.put("AA", 213); //正是因为key是不可重复的所有Entry才不可重复。

        map.put("BB", 456);

        map.put(123, "CC");

        map.put(null, null);

        map.put(new Person("DD",23), 89);

       

        //1、遍历key集(用".keySet"):输出的结果与添加进HashMap的顺序不同。

        Set set=map.keySet();

        for(Object obj:set) {

            System.out.println(obj);

        }System.out.println("        ******       ");

        //2、遍历value集:用".values"

        Collection values=map.values();

        Iterator i=values.iterator();

        while(i.hasNext()) {

            System.out.println(i.next());

        }

        //3、如何遍历key-value对

//      方式一:

        Set set1=map.keySet();

        for(Object obj:set1) {//通过key找相应的value值

            System.out.println(obj+"------>"+map.get(obj));

        }

//      方式二:

        Set set2=map.entrySet();

        for(Object obj:set2) {

            Map.Entry entry=(Map.Entry)obj;//创建一个Map.Entry类型的。

//          System.out.println(entry.getKey()+"------>"+entry.getValue());

            System.out.println(entry);

        }

       

    }

}

 

 

二、LinkedHashMap的使用:

LinkedHashMap:使用链表维护添加进Map中的顺序。故遍历Map时,是按照添加的顺序遍历的。

public class TestMap {

    /*

     * LinkedHashMap:使用链表维护添加进Map中的顺序。故遍历Map时,是按照添加的顺序遍历的。

     * */

    @Test

    public void testLinkedHashMap() {

        Map map=new LinkedHashMap();

        map.put("AA ", 213);

        map.put("123", 34);

        map.put(456, 22);

        map.put(new Person("MM",23), 80);

       

        Set set=map.keySet();

        for(Object obj:set) {

            System.out.println(obj+"------>"+map.get(obj));

        }

       

    }

}

 

三、TreeMap的使用:

       TreeMap:按照添加进Map中的元素的key的指定属性进行排序。 要求:key必须是同一个类对象。(自然排序 & 定制排序)

 

①、定制排序与自然自然排序的代码解析:

 

public class TestMap {

//|------TreeMap:按照添加进Map中的元素的key的指定属性进行排序。 要求:key必须是同一个类对象。

    //定制排序

    @Test

    public void testTreeMap2() {

        Comparator com=new Comparator() {



            @Override      //实现排序的方式

            public int compare(Object o1, Object o2) {

                if(o1 instanceof Customer && o2 instanceof Customer) {

                   Customer c1=(Customer)o1;

                   Customer c2=(Customer)o2;

                   int i=c1.getId().compareTo(c2.getId());

                   if(i==0) {

                       return c1.getName().compareTo(c2.getName());

                   }

                   return i;

                }

                return 0;

            }

        };

        Map map=new TreeMap();

        map.put(new Person("AA",23), 80);

        map.put(new Person("MM",23), 70);

        map.put(new Person("CC",13), 80);

        map.put(new Person("BB",43), 60);

        Set set=map.keySet();

        for(Object obj:set) {

            System.out.println(obj+"------>"+map.get(obj));

        }

    }

    //自然排序

    @Test

    public void testTreeMap() {

        Map map=new TreeMap();

        map.put(new Person("AA",23), 80);

        map.put(new Person("MM",22), 70);

        map.put(new Person("CC",13), 80);

        map.put(new Person("BB",43), 60);

       

        Set set=map.keySet();

        for(Object obj:set) {

            System.out.println(obj+"------>"+map.get(obj));

        }

       

    }


 

四、Map实现类之4 : HashTable;HashTable的子类Properties的使用:

1、使用Properties处理属性文件(讲的是输出属性文件中key对应的value属性值):

①、Eclipse中在java project中右击  à  new à file à命名一个文件名 à点击确定后在新建的文件里写key与value,即键值对。

 

2、关于properties的代码解析:

①、jdbc.properties文件

文件的内部写法如下:

user=name

password=123

②、代码实现:

public class TestMap {

    /*

     * 使用Properties处理属性文件(讲的是输出属性文件中key对应的value属性值)

     * */

    @Test

    public void testProperties() throws FileNotFoundException, IOException{

        Properties pros=new Properties();

        pros.load(new FileInputStream("jdbc.properties"));//到此为止已经可以用load载入"jdbc.properties"文件了

       

        String user=pros.getProperty("user");//获取属性文件"jdbc.properties"中的数据

        System.out.println(user);  //将属性文件中的信息逮入进来

        String pass=pros.getProperty("password");

        System.out.println(pass);

       

    }

}

 

 

以上所有代码的总合:

1、Person类:

package com.atguigu.Map00;

public class Person implements Comparable{
	int id=1002;
	
	
	private String name;
	private Integer age;
	//有参的构造方法
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public Person() {	//无参的构造方法
		super();
	}
	
	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 void walk() {
		System.out.println("人走路");
	}
	public void eat() {
		System.out.println("人吃饭");
	}
	@Override	//用于Set接口比较
	public int hashCode() {//1、return age.hashCode()+name.hashCode();没有下述的健壮性好。
		//2、建议直接用系统自动生成的。
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + id;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
//		3、return init++;//不建议这样用
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (id != other.id)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	//向TreeSet中添加Person类的对象时,依据此方法,确定按哪个属性排列。
	@Override
	public int compareTo(Object o) {
		if(o instanceof Person) {
			Person p=(Person)o;
//			return this.name.compareTo(p.name);//此处是按照name属性进行排序的。
//			return -this.age.compareTo(p.age);//加上负号表示由大到小
			//			return this.age.compareTo(p.age);//按照age进行排序(age是Integer类型的,Integer也实现了compareTo方法)。
//			自然排序:要求自定义类实现java.lang.Comparable接口并重写其compareTo(Object obj)方法
//			 在此方法中,指明按照自定义类的哪个属性进行排序。
//			为了使相同的也能写进TreeSet像数据库一样,有一级排序,一级排序相同再二级排序
			
			/*实现的是先按照age从小到大排,age相等按name排*/
			int i=this.age.compareTo(p.age);
			if(i==0) {//如果有age相等的则按名字排序
				return this.name.compareTo(p.name);
			}else {//如果age不等则按age排序
				return i;
			}
		}
		return 0;
	}
	
	
}

 

2、Customer类:

package com.atguigu.Map00;

public class Customer {
	private String name;
	private int id;
	//Getters & Setters方法
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	//构造器
	public Customer(String name, int id) {
		super();
		this.name = name;
		this.id = id;
	}
	//toString方法
	@Override
	public String toString() {
		return "Customer [name=" + name + ", id=" + id + "]";
	}
	//hashCode & equals()方法
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		result = prime * result + ((name == null) ? 0 : name.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;
		Customer other = (Customer) obj;
		if (id != other.id)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
}

 

3、TestMap类:(所有Map相关的子接口及子接口的实现类);此类由多个单元测试组成。

package com.atguigu.Map00;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;

/*
 * Collection接口
 * 
 * Map接口
 * 			|------HashMap:Map的主要实现类
 * 			|------LinkedHashMap:
 * 			|------TreeMap:
 * 			|------HashTable
 * 				|------Properties
 * */
import org.junit.Test;
/*
 * Collection接口
 * 
 * Map接口
 * 			|------HashMap:Map的主要实现类
 * 			|------LinkedHashMap:使用链表维护添加进Map中的顺序。故遍历Map时,是按照添加的顺序进行遍历的。
 * 			|------TreeMap:按照添加进Map中的元素的key的指定属性进行排序。	要求:key必须是同一个类对象。
 * 					自然排序 & 定制排序			
 * |------HashTable:古老的实现类,线程安全,不建议使用。
 * 				|------Properties:常用来处理属性文件。特点:键和值都为String类型的。
 * */

import com.atguigu.Collection.Customer;

public class TestMap {
	/*
	 * 使用Properties处理属性文件(讲的是输出属性文件中key对应的value属性值)
	 * */
	@Test
	public void testProperties() throws FileNotFoundException, IOException{
		Properties pros=new Properties();
		pros.load(new FileInputStream("jdbc.properties"));//到此为止已经可以用load载入"jdbc.properties"文件了
		
		String user=pros.getProperty("user");//获取属性文件"jdbc.properties"中的数据
		System.out.println(user);	//将属性文件中的信息逮入进来
		String pass=pros.getProperty("password");
		System.out.println(pass);
		
	}
	
	
	
	
//|------TreeMap:按照添加进Map中的元素的key的指定属性进行排序。	要求:key必须是同一个类对象。
	//定制排序
	@Test
	public void testTreeMap2() {
		Comparator com=new Comparator() {

			@Override		//实现排序的方式
			public int compare(Object o1, Object o2) {
				if(o1 instanceof Customer && o2 instanceof Customer) {
					Customer c1=(Customer)o1;
					Customer c2=(Customer)o2;
					int i=c1.getId().compareTo(c2.getId());
					if(i==0) {
						return c1.getName().compareTo(c2.getName());
					}
					return i;
				}
				return 0;
			}
		};
		Map map=new TreeMap();
		map.put(new Person("AA",23), 80);
		map.put(new Person("MM",23), 70);
		map.put(new Person("CC",13), 80);
		map.put(new Person("BB",43), 60);
		Set set=map.keySet();
		for(Object obj:set) {
			System.out.println(obj+"------>"+map.get(obj));
		}
	}
	//自然排序
	@Test
	public void testTreeMap() {
		Map map=new TreeMap();
		map.put(new Person("AA",23), 80);
		map.put(new Person("MM",22), 70);
		map.put(new Person("CC",13), 80);
		map.put(new Person("BB",43), 60);
		
		Set set=map.keySet();
		for(Object obj:set) {
			System.out.println(obj+"------>"+map.get(obj));
		}
		
	}
	
	
	
	
	/*
	 * LinkedHashMap:使用链表维护添加进Map中的顺序。故遍历Map时,是按照添加的顺序遍历的。
	 * */
	@Test
	public void testLinkedHashMap() {
		Map map=new LinkedHashMap();
		map.put("AA ", 213);
		map.put("123", 34);
		map.put(456, 22);
		map.put(new Person("MM",23), 80);
		
		Set set=map.keySet();
		for(Object obj:set) {
			System.out.println(obj+"------>"+map.get(obj));
		}
		
	}
	
	
	
	/*
	 * 如何遍历Map
	 * Set keySet()
	 * Collection values()
	 * Set entrySet()
	 * */
	@Test
	public void testMap2() {
		Map map=new HashMap();
		map.put("AA", 213);	//正是因为key是不可重复的所有Entry才不可重复。
		map.put("BB", 456);
		map.put(123, "CC");
		map.put(null, null);
		map.put(new Person("DD",23), 89);
		
		//1、遍历key集(用".keySet"):输出的结果与添加进HashMap的顺序不同。
		Set set=map.keySet();
		for(Object obj:set) {
			System.out.println(obj);
		}System.out.println("        ******       ");
		//2、遍历value集:用".values"
		Collection values=map.values();
		Iterator i=values.iterator();
		while(i.hasNext()) {
			System.out.println(i.next());
		}
		//3、如何遍历key-value对
//		方式一:
		Set set1=map.keySet();
		for(Object obj:set1) {//通过key找相应的value值
			System.out.println(obj+"------>"+map.get(obj));
		}
//		方式二:
		Set set2=map.entrySet();
		for(Object obj:set2) {
			Map.Entry entry=(Map.Entry)obj;//创建一个Map.Entry类型的。
//			System.out.println(entry.getKey()+"------>"+entry.getValue());
			System.out.println(entry);
		}
		
	}
	
	
	
	/*
	 * HashMap:
	 * 1、key是用Set来存放的,不可重复。value是用Collection来存放的,可重复;
	 *一个key-value对,是一个Entry。所有的Entry是用Set存放的,也是不可重复的。
	 * 2、向HashMap中添加元素时,会调用key所在类的equals()方法,判断两个key是否相同。
	 * 若相同则只能添加进后添加的那个元素。
	 * */
	@Test
	public void testMap1() {
		Map map=new HashMap();	//1、Object put(Object key,Object value):向Map中添加一个元素
//		map.put(key, value);
		map.put("AA", 213);	//正是因为key是不可重复的所有Entry才不可重复。
		map.put("BB", 456);
		map.put("BB", 456);
		map.put(123, "CC");
		map.put(null, null);
		map.put(new Person("DD",23), 89);//put的两个Person实体类对象添加成功一个,因为key值不能相等。
		map.put(new Person("DD",23), 98);
		System.out.println(map.size());//结果为:4(因为put()里添加了一个key值重复的,只能算一个。)
		System.out.println(map);
/*
 * 结果:
5
{AA=213, BB=456, null=null, 123=CC, com.atguigu.Map00.Person@14c8c=98}
*/
		map.remove("AA");
		System.out.println(map.size());
		System.out.println(map);
//		map.clear();	//clear:清空Map集合
		System.out.println(map.get(123));//get:输出key值为123对应的value值;如果没有此key则返回null。
	}
}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值