Map接口
- Map与Collection接口并列存在。用于保存具有映射关系的数据key-value。
- Map中的key和value都可以是任何应用类型的数据。
- Map中的key用Set来存放,不允许重复,即同一个Map对象所对应的类,须重写equals()和hashCode()方法。
- 常用String类作为Map的“键”
- key和value之间存在单向一对一关系,即通过指定的key总能找到唯一的、确定的value。
- Map接口中常用的实现类:HashMap、TreeMap和Properties。
Map和Set有很多相似之处,通过看源码就可以看出来。HashSet的源码如下所示:
public HashSet() {
map = new HashMap<>();
}
Map常用方法
添加删除操作
- Object put(Object key, Object value)
- Object remove(Object key)
- void putAll(Map t)
- void clear()
元素查询的操作
- Object get(Object key)
- boolean containsKey(Object key)
- boolean containsValue(Object value)
- int size()
- boolean isEmpty()
- boolean equals(Object obj)
元视图操作的方法
- Set keySet()
- Collection values()
- Set entrySet()
这三种方法主要是用来遍历Map中的元素,以HashMap为例
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
public class TestMap {
@Test
public void test() {
Map map = new HashMap();
map.put("AA", 123);
map.put(456,"BB");
map.put(null, null);
map.put(new Person(15,"xiaowang"), 10);
//1.遍历key集
System.out.println("-----遍历key集-----");
Set set = map.keySet();
for(Object obj : set) {
System.out.println(obj);
}
//2.遍历value集
System.out.println("\n-----遍历value集-----");
Collection values = map.values();
Iterator iterator = values.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
//3.遍历key-values对
System.out.println("\n-----遍历key-values对-----");
//方式一
System.out.println("-----方式一-----");
Set set1 = map.keySet();
for(Object obj : set1) {
System.out.println(obj + "--->" + map.get(obj));
}
//方式二
System.out.println("-----方式二-----");
Set set2 = map.entrySet();
for(Object obj : set2) {
Map.Entry entry = (Map.Entry)obj;
System.out.println(entry.getKey() + "--->" + entry.getValue());
}
}
}
结果如下所示:
HashMap
- HashMap是Map接口使用频率最高的实现类
- 允许使用null键和null值,与HashSet一样,不保证映射的顺序
- HashMap判断两个key相等的标准是:两个key通过equals()方法返回true,并且哈希值也相等
- HashMap判断两个value相等的标准是:两个value通过equals()方法返回true
LinkedHashMap
LinkedHashMap与LinkedHashSet一致,都是用链表维护了添加的顺序。因此遍历的时候,是按添加的顺序遍历的。
TreeMap
按照添加进Map中的元素的key的特定属性进行排序。要求:key必须是同一个类的对象。
对TreeMap遍历,与TreeSet类似,也有自然排序和定制排序
TreeMap中的自然排序
package 集合;
public class Person implements Comparable{//自然排序一定要实现Comparable接口
private int age;
private String name;
public Person(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
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;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Person [age=" + age + ", name=" + name + "]";
}
@Override
public int compareTo(Object o) {
if(o instanceof Person) {
Person p = (Person)o;
int i = this.age - p.age;
if(i == 0) {
return this.name.compareTo(p.name);
}else {
return i;
}
}
return 0;
}
}
测试类
package 集合;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.junit.Test;
public class TestMap {
//自然排序
@Test
public void test2() {
Map map = new TreeMap();
map.put(new Person(10, "z"), 10);
map.put(new Person(30, "a"), 80);
map.put(new Person(50, "t"), 90);
map.put(new Person(10, "c"), 30);
map.put(new Person(20, "b"), 40);
Set set1 = map.keySet();
for(Object obj : set1) {
System.out.println(obj + "--->" + map.get(obj));
}
}
}
结果如下所示
TreeMap中的定制排序
package 集合;
public class Customer {
private Integer age;
private String name;
public Customer(Integer age, String name) {
super();
this.age = age;
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((age == null) ? 0 : age.hashCode());
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 (age == null) {
if (other.age != null)
return false;
} else if (!age.equals(other.age))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Customer [age=" + age + ", name=" + name + "]";
}
}
测试类
package 集合;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.junit.Test;
public class TestMap {
//定制排序
@Test
public void test3() {
//1. 创建一个实现了Comparator接口的类对象
Comparator com = new Comparator(){
//向TreeMap中添加Customer类的对象,在此compare()方法中,指明是按照Customer的哪个属性进行排序的
@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.getAge().compareTo(c2.getAge());
if(i == 0) {
return c1.getName().compareTo(c2.getName());
}else {
return i;
}
}
return 0;
}
};
//2. 将此对象作为形参传递给TreeMap的构造器中
TreeMap map = new TreeMap(com);
//3. 向TreeMap中添加Comparator接口中的compare方法中涉及的类的对象
map.put(new Customer(10, "w"), 10);
map.put(new Customer(30, "a"), 20);
map.put(new Customer(20, "b"), 30);
map.put(new Customer(50, "t"), 40);
map.put(new Customer(60, "y"), 50);
Set set1 = map.keySet();
for(Object obj : set1) {
System.out.println(obj + "--->" + map.get(obj));
}
}
}
结果如下所示
定制排序适用于,不能修改自定义类中的代码,只需要在测试类中修改就可以实现排序。
HashTable
- HashTable是HashMap古老的实现类,线程安全
- 与HashMap不同,HashTable不允许使用null作为key和value
- 与HashMap一样,HashTable也不能保证其中key-value的顺序
- HashTable判断两个key相等、判断两个value相等的标准与HashMap一致
- HashTable有一个子类Properties,常用来处理属性文件,键和值都是String类型的
接下来是使用Properties的一个例子
首先在工程目录下新建一个jdbc.properties文件(文件名可以随意起),文件中的内容如下所示
注:文件内容不能有空格,以保证其实字符串类型的
user=wu
password=123
测试类中的代码如下
@Test
public void test() throws FileNotFoundException, IOException {
Properties pros = new Properties();
pros.load(new FileInputStream(new File("jdbc.properties")));
String user = pros.getProperty("user");
String password = pros.getProperty("password");
System.out.println("user:" + user + ", password:" + password);
}
于是就可以得到如下结果