Map(支持泛型)架构:


实际上还有Properties继承HashTable。 常用Map操作类有Java.util.HashMap与Java.util.TreeMap。HashTable不建议用,但子类Properties常用。 1、HashMap 建立Map操作对象时,可以使用泛型语法指定键与值的类型。要建立键值对应,可以使用put()方法,第一个自变量是键,第二个自变量是值。对于Map而言,键不会重复,判断键是否重复是根据 hashCode()与 equals(),所以作为键的对象必须操作 hashcode()与 equals()。若要指定键取回对应的值则使用get()方法。例如:

package coll_map;
import java.util.*;
import static java.lang.System.out;

public class MapDemo {
	public static void main(String[] args) {
		Map<String,String> detail=new HashMap<>(); 
		detail.put("张三","巴拉巴拉");
		detail.put("李四","巴巴拉拉");
		detail.put("王二","拉拉巴巴");
		
		Scanner scan=new Scanner(System.in);
		out.println("检索信息:");
		out.println(detail.get(scan.nextLine()));
		out.println(detail);
	}
}

复制代码


2、TreeMap 在 HashMap中建立键值对应之后,键是无序的,这可以在执行结果中看到。如果想让键是有序的,则可以使用 TreeMap。 如果使用 TreeMap建立键值对应,则 键的部分将会排序,条件是作为键的对象必须操作 Comparable接口,或者是在创建TreeMap 时指定操作 Comparator接口的对象。例如:


package coll_map;

import java.util.*;
import static java.lang.System.out;

public class TreeMapDemo {

	public static void main(String[] args) {
		Map<String, String> detail = new TreeMap<>();
		detail.put("张三", "巴拉巴拉");
		detail.put("李四", "巴巴拉拉");
		detail.put("王二", "拉拉巴巴");

		Scanner scan = new Scanner(System.in);
		out.println("检索信息:");
		out.println(detail);

	}
}

复制代码


如果执行出相反结果,操作Comparator:

package coll_map;

import java.util.*;
import static java.lang.System.out;

public class TreeMapDemo {

	public static void main(String[] args) {
		Map<String, String> detail = new TreeMap<>((s1,s2)->-s1.compareTo(s2));
		detail.put("张三", "巴拉巴拉");
		detail.put("李四", "巴巴拉拉");
		detail.put("王二", "拉拉巴巴");

		Scanner scan = new Scanner(System.in);
		out.println("检索信息:");
		out.println(detail);
	}
}

复制代码

在创建TreeMap时指定StringComparator实例。 3、Properties properties类继承自 HashTable, HashTable操作了Map接口 , roperties自然也有Map的行为。虽然也可以使用put()设定键值对、get()方法指定键取回值,不过一般常用 Properties的 setProperty()指定字符串类型的键值, getProperty()指定字符串类型的键取回字符串类型的值,通常称为属性名称与属性值。例如:

package coll_map;

import java.util.*;

public class PropertiesDemo {
	public static void main(String[] args) {
		Properties pro = new Properties();
		pro.setProperty("username", "JackChan");
		pro.setProperty("password", "123456");
		System.out.println(pro.getProperty("username"));
		System.out.println(pro.getProperty("password"));
	}
}

复制代码

Properties也可以从文档中读取属性,例如若有个 test.txt文档如下


properties的=左边设定属性名称,右边设定属性值。可以使用 Properties的load()方法指定 Inputstream的实例,如 FileInputstream,从文档中加载属性。例如:

package coll_map;

import java.io.*;
import java.util.*;

public class PropertiesDemo {
	public static void main(String[] args) throws FileNotFoundException, IOException {
		Properties pro = new Properties();
		pro.load(new FileInputStream("B:\\test.properties"));
		System.out.println(pro.getProperty("user"));
	}
}

复制代码

执行结果:


load方法结束后自动关闭InputStream实例。Properties 可载入.properties 文档和.xml文档。文件格式:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment></comment>
<entry key="user">JackChan</entry>
<entry key="pw">123456</entry>
</properties>
复制代码

要用loadFromXML()加载.xml文档:

package coll_map;

import java.io.*;
import java.util.*;

public class PropertiesDemo {
	public static void main(String[] args) throws FileNotFoundException, IOException {
		Properties pro = new Properties();
		pro.loadFromXML(new FileInputStream("B:\\test.xml"));
		System.out.println(pro.getProperty("user"));
		System.out.println(pro.getProperty("pw"));
	}
}

复制代码

可以使用System的static方法getProperties()方法取得Properties实例,该实例包括系统属性:Properties pro1 = System.getProperties(); 可以用-D指定系统属性:>java -Duser=JackChan -Dpw=1234556 LoadSystemProps System.getProperties()返回的实例也包括许多默认属性,如System.out.println(pro1.getProperty("java.version"));java.version取得JRE版本,java.class.path取得类路径,可以查阅API文件看详细的。 3、访问Map键值 如果要取得Map中所有键,可以调用keySet()方法,返回的是Set对象(因为键是不重复)。用values()返回Collection对象,可以取得Map所有值。

package coll_map;
import java.util.*;
import static java.lang.System.out;

public class MapDemo {
	public static void main(String[] args) {
		Map<String,String> detail=new HashMap<>(); 
		detail.put("张三","巴拉巴拉");
		detail.put("李四","巴巴拉拉");
		detail.put("王二","拉拉巴巴");
		
		out.println("显示所有键");
		//keySet返回Set可以用Iterable新增的forEach()方法,用lambda语法重写
		detail.keySet().forEach(key->out.println(key));
		out.println("显示所有值");
		//因为values()返回collection对象可以用lambda语法
		detail.values().forEach(value->out.println(value));
	}
}
复制代码

自己写forEach()结果一样:

static void forEach(Iterable<String> iterable){
	for(String elem:iterable){
		out.println(elem);
	}
}
复制代码

如果同时取得键和值,可以用entrySet()方法,返回Set对象每个元素又是Map.Entry实例,然后就可以用getKey()、getValue()取键值:

package coll_map;
import java.util.*;
import static java.lang.System.out;

public class MapDemo {
	public static void main(String[] args) {
		Map<String,String> detail=new HashMap<>(); 
		detail.put("张三","巴拉巴拉");
		detail.put("李四","巴巴拉拉");
		detail.put("王二","拉拉巴巴");
		foreach(detail.entrySet());
	}
	static void foreach(Iterable<Map.Entry<String, String>> iterable) {
		for(Map.Entry<String, String> entry:iterable) {
			out.printf("(键%s,值%s)%n",entry.getKey(),entry.getValue());
		}
	}
}
复制代码

直接用forEach方法:detail.forEach((key,value)->out.printf(key,value)); Map没有继承Iterable,forEach是定义在Map接口上的,接受java.util.function.Biconsumer<T,U>接口实例,这个接口只有一个抽象方法void accept(T t,U u)必须操作,两个参数分别接受迭代的键值。