在生活中有许多带有映射关系的数据,比如一个身份证号就对应一个人,那么我们如何存储这样的数据呢,在Java中为我们提供了另外的集合:Map集合。Map集合常用的实现类有( HashMap, Hashtable, LinkedHashMap TreeMap Properties)
Map集合属于双列集合,是通过键来找值;在Map集合中键不能重复,每个键也只能对应一个值。如果键相同的时候,就会把旧值覆盖,然后返回旧值。还有就是Map集合中的数据结构只和键有关,和值无关,值只是键映射的一个数据;键是怎样的顺序,值就为相应的顺序。
一、Map集合的功能
1、添加功能
- V put(K key,V value):添加元素。这个其实还有另一个功能就是替换。如果键是第一次存储,就直接存储元素,返回null;如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值。
2、删除功能
- void clear():移除所有的键值对元素
- V remove(Object key):根据键删除键值对元素,并把值返回
3、判断功能
- boolean containsKey(Object key):判断集合是否包含指定的键
- boolean containsValue(Object value):判断集合是否包含指定的值
- boolean isEmpty():判断集合是否为空
4、获取功能
- Set<Map.Entry<K,V>> entrySet(): 返回一个键值对的Set集合
- V get(Object key):根据键获取值
- Set keySet():获取集合中所有键的集合
- Collection values():获取集合中所有值的集合
二、HashMap集合
HashMap集合是Map集合的实现类。HashMap允许键为 null 和值为 null。一般我们都使用HashMap来实现Map集合,因为HashMap 集合实现 Map 集合添加元素和删除映射关系效率更高
import java.util.HashMap;
public class MyTest {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
String v = map.put("1", "张三");
//第一次存储键 "1",返回null
System.out.println(v);
//当发生键相同的时候,值就会覆盖,返回的是旧值
v = map.put("1", "李四");
System.out.println(v);
map.put("2", "李李");
map.put("3", "王王");
map.put("4", "冯冯");
System.out.println(map);
}
}
//运行结果为
null
张三
{1=李四, 2=李李, 3=王王, 4=冯冯}
如果我们想要对Map集合进行遍历我们可以通过键来找值。还可以把这个Map集合中的键值对放到一个Set集合中然后分别获取键和值来进行输出。
方式一(通过键找值)
public class MyTest3 {
public static void main(String[] args) {
HashMap<Integer, String> hashMap = new HashMap<>();
hashMap.put(1, "bbb");
hashMap.put(2, "ccc");
hashMap.put(3, "ddd");
hashMap.put(4, "eee");
hashMap.put(5, "fff");
//获取hashMap集合的键
Set<Integer> integers = hashMap.keySet();
for (Integer key : integers) {
System.out.println(key + "===" + hashMap.get(key));
}
}
}
方式二(分别获取键和值)
public class MyTest4 {
public static void main(String[] args) {
HashMap<Integer, String> hashMap = new HashMap<>();
hashMap.put(1, "bbb");
hashMap.put(2, "ccc");
hashMap.put(3, "ddd");
hashMap.put(4, "eee");
hashMap.put(5, "fff");
//entrySet() 获取键值对 放到Set集合里面去
Set<Map.Entry<Integer, String>> entries = hashMap.entrySet();
//K getKey ()
//返回与此项对应的键。
//V getValue ()
//返回与此项对应的值。
for (Map.Entry<Integer, String> entry : entries) {
//System.out.println(entry);
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"==="+value);
}
}
}
当HashMap集合存储的键为自定义类的时候我们还需要重写 hashCode方法 和 equals 方法来保证键的唯一。
三、TreeMap集合
TreeMap集合的键数据结构为红黑树,这样可以保证键的唯一性和可排序,排序也分为自然排序和比较器排序(方式和TreeSet一样)。定义一个学生类,并进行测试
Student类
import java.util.Objects;
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public int compareTo(Student o) {
int num=this.age-o.age;
int num2=num==0?this.name.compareTo(o.name):num;
return num2;
}
}
自然排序
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class MyTest {
public static void main(String[] args) {
TreeMap<Student, String> treeMap = new TreeMap<>();
treeMap.put(new Student("张三0", 23), "111");
treeMap.put(new Student("张三0", 23), "222");
treeMap.put(new Student("张三0", 23333), "222");
treeMap.put(new Student("张三1", 24), "444");
treeMap.put(new Student("张三2", 26), "555");
treeMap.put(new Student("张三3", 25), "666");
treeMap.put(new Student("张三4", 28), "777");
Set<Map.Entry<Student, String>> entries = treeMap.entrySet();
for (Map.Entry<Student, String> entry : entries) {
Student key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"==="+value);
}
}
}
比较器排序
import java.util.Comparator;
import java.util.TreeMap;
public class MyTest2 {
public static void main(String[] args) {
TreeMap<Student, String> treeMap = new TreeMap<>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int num = s1.getAge()-s2.getAge();
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
return -num2;
}
});
treeMap.put(new Student("张三0", 23), "111");
treeMap.put(new Student("张三0", 23), "222");
treeMap.put(new Student("张三0", 23333), "222");
treeMap.put(new Student("张三1", 24), "444");
treeMap.put(new Student("张三2", 26), "555");
treeMap.put(new Student("张三3", 25), "666");
treeMap.put(new Student("张三4", 28), "777");
Set<Map.Entry<Student, String>> entries = treeMap.entrySet();
Set<Map.Entry<Student, String>> entries = treeMap.entrySet();
for (Map.Entry<Student, String> entry : entries) {
Student key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "===" + value);
}
}
}
上面的代码分别是TreeMap的两种排序方法。 TreeMap集合的线程是不安全的但是效率比较高。
四、Collections类
Collections类是针对集合操作的工具类,它有多种成员方法来对集合进行操作。
1. public static void sort(List list): 排序,默认按照自然顺序
2. public static int binarySearch(List<?> list,T key): 二分查找
3. public static T max(Collection<?> coll): 获取最大值
4. public static void reverse(List<?> list): 反转
5. public static void shuffle(List<?> list): 随机置换(随机打乱顺序,如斗地主的洗牌阶段)
实例代码如下:
import java.util.ArrayList;
import java.util.Collections;
public class MyTest {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(100);
list.add(1002);
list.add(1030);
list.add(1050);
list.add(100);
//对list集合排序
Collections.sort(list);
System.out.println(list);
//通过二分查找获取索引
int i = Collections.binarySearch(list, 1050);
System.out.println(i);
System.out.println(Collections.max(list)); //获取最大值
System.out.println(Collections.min(list)); //获取最小值
Collections.reverse(list);//反转集合中的元素
System.out.println(list);
Collections.shuffle(list);//随机打乱集合中元素的顺序
System.out.println(list);
}
}
//运行结果为
[100, 100, 1002, 1030, 1050]
4
1050
100
[1050, 1030, 1002, 100, 100]
[100, 1050, 1030, 1002, 100]
此类完全由在 Collection 上进行操作或返回 Collection 的静态方法组成,所有可以通过类名直接调用方法。