赞
踩
为了应对不同的场景需要,所以提供很多集合,总体来说分成单列集合和双列集合
注意:Map系列集合的特点都是由键决定的,值只是一个附属品,值是不做要求的
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
public class MapTest {
public static void main(String[] args) {
Map<String,Integer> map =new HashMap<>();//一行经典代码。按照键 无序,不重复,无索引。
map.put("手表",100);
map.put("手表",220); //后面重复的数据会覆盖前面的数据(键决定的)
map.put("手机",3);
map.put("Java",3);
map.put(null,null);
System.out.println(map);
Map<String,Integer> map2 =new LinkedHashMap<>();//一行经典代码。按照键 //有序,不重复,无索引。
map2.put("手表",100);
map2.put("手表",220);
map2.put("手机",3);
map2.put("Java",3);
map2.put(null,null);
System.out.println(map2);
Map<Integer,String>map1=new TreeMap<>();// 可排序,不重复,无索引
map1.put(23,"Java");
map1.put(23,"MySQL");
map1.put(19,"李四");
map1.put(20,"王五");
System.out.println(map1);
}
}
为什么要先学习Map的常用方法?
Map是双列集合的祖宗,它的功能是全部双列集合都可以继承过来使用的,Map的常用方法如下
import java.util.*;
public class MapTest {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();//一行经典代码。按照键 无序,不重复,无索引。
map.put("手表", 100);
map.put("手表", 220); //后面重复的数据会覆盖前面的数据(键决定的)
map.put("手机", 3);
map.put("Java", 3);
map.put(null, null);
System.out.println(map);
//2.public int size():获取集合的大小
System.out.println(map.size());
// 3、public void clear():清空集合
//map.clear();System.out.println(map);
// 4.public boolean isEmpty():判断集合是否为空,为空返回true,反之!
System.out.println(map.isEmpty());
//5.public v get(object key)根据键获取对应值
int v1 = map.get("手表");
System.out.println(v1);
System.out.println(map.get("手机"));//3
System.out.println(map.get("张三"));// nulL
//6.public Vremove(object key):根据键删除整个元素(删除键会返回键的值)
System.out.println(map.remove("手表"));
System.out.println(map);
//7.public boolean containsKey(0bject key):判断是否包含某个键 ,包含返回true,反之
System.out.println(map.containsKey("手表"));// false
System.out.println(map.containsKey("手机"));//true
System.out.println(map.containsKey("java"));//false
System.out.println(map.containsKey("Java"));//true
//8.public boolean containsValue(object value): 判断是否包含某个值。
System.out.println(map.containsValue(2));//true
System.out.println(map.containsValue("2"));// false
//9.public Set<K> keySet(): 获取Map集合的全部键
Set<String> keys = map.keySet();
System.out.println(keys);
//10.public Collection<V>values();获取Map集合的全部值,
Collection<Integer> values = map.values();
System.out.println(values);
// 11.把其他Map集合的数据倒入到自己集合中来。(拓展)
Map<String, Integer> map1 = new HashMap<>();
map1.put("java1", 10);
map1.put("java2", 20);
Map<String, Integer> map2 = new HashMap<>();
map2.put("java3", 10);
map2.put("java2", 222);
map1.putAll(map2);// putAl:把map2集合中的元素全部倒入一份到map1集合中去。
}
}
Map集合遍历的三种方式
Map的方法
import java.util.*;
public class MapTest {
public static void main(String[] args) {
Map<String, Double> map = new HashMap<>();//一行经典代码。按照键 无序,不重复,无索引。
map.put("蜘蛛精",162.5);
map.put("蜘蛛精",169.8);
map.put("紫霞",165.8);
map.put("至尊宝",169.5);
map.put("牛魔王",183.6);
System.out.println(map);
// map = {蜘蛛精=169.8,牛魔王=183.6,至尊宝=169.5,紫霞=165.8}
//1、获取Map集合的全部键
Set<String> keys = map.keySet();
System.out.println(keys);
// 2、遍历全部的键,根据键获取其对应的值
for(String key :keys) {
// 根据键获取对应的值
double value = map.get(key);
System.out.println(key + "=====>" + value);
}
}
}
遍历Map集合方式一:键找值流程
getkey
获取key getValue
获取值import java.util.*;
public class MapTest {
public static void main(String[] args) {
Map<String, Double> map = new HashMap<>();//一行经典代码。按照键 无序,不重复,无索引。
map.put("蜘蛛精",162.5);
map.put("蜘蛛精",169.8);
map.put("紫霞",165.8);
map.put("至尊宝",169.5);
map.put("牛魔王",183.6);
System.out.println(map);
// map = {蜘蛛精=169.8,牛魔王=183.6,至尊宝=169.5,紫霞=165.8}
// entries =[(蜘蛛精=169.8),(牛魔王=183.6),(至宝=169.5),(紫霞=165.8)]
// entry
//1、调用Map集合提供entrySet方法,把Map集合转换成键值对类型的Set集合
Set<Map.Entry<String,Double>> entries = map.entrySet();
for(Map.Entry<String,Double>entry:entries) {
String key = entry.getKey();
double value = entry.getValue();
System.out.println(key +"---->"+ value);
}
}
}
需要用到Map的如下方法:
public class MapTest {
public static void main(String[] args) {
Map<String, Double> map = new HashMap<>();//一行经典代码。按照键 无序,不重复,无索引。
map.put("蜘蛛精",162.5);
map.put("蜘蛛精",169.8);
map.put("紫霞",165.8);
map.put("至尊宝",169.5);
map.put("牛魔王",183.6);
System.out.println(map);
// map = {蜘蛛精=169.8,牛魔王=183.6,至尊宝=169.5,紫霞=165.8}
// entries =[(蜘蛛精=169.8),(牛魔王=183.6),(至宝=169.5),(紫霞=165.8)]
// entry
map.forEach((k,v)->{
System.out.println(k +"--->" + v);
});
map.forEach(new BiConsumer<String,Double>() {
@Override
public void accept(String k, Double v) {
System.out.println(k + "---->" + v);
}
});
}
}
lambda表达式的优化
map.forEach(new BiConsumer<String,Double>() {
@Override
public void accept(String k, Double v) {
System.out.println(k + "---->" + v);
}
});
优化成这个样子
map.forEach((k,v)->{
System.out.println(k +"--->" + v);
});
需求:
分析
import java.util.*;
import java.util.function.BiConsumer;
public class MapTest {
public static void main(String[] args) {
// 1、把80个学生选择的景点数据拿到程序中来。
List<String> data = new ArrayList<>();
String[] selects ={"A","B","C","D"};
Random r=new Random();
for(int i = 1; i <= 80; i++) {
// 每次模拟一个学生选择一个景点,存入到集合中去。
int index = r.nextInt(4);//0 1 2 3
data.add(selects[index]);
}
System.out.println(data);
// 2、开始统计每个景点的投票人数
// 准备一个Map集合用于统计最终的结果
Map<String,Integer> result =new HashMap<>();
// 3、开始遍历80个景点数据
for(String s:data){
// 问间Map集合中是否存在该景点
if(result.containsKey(s)){
// 说明这个景点之前统计过。其值+1.存入到Map集合中去
result.put(s,result.get(s)+1);
}else {
result.put(s,1);
}
}
// 说明这个景点是第一次统计,存入"景点=1
System.out.println(result);
}
}
HashMap(由键决定特点):无序、不重复、无索引;(用的最多》
只要键数据
,不要值数据而已
JDK8之前,哈希表=数组+链表
JDK8开始,哈希表=数组+链表+红黑树
哈希表是一种增删改查数据,性能都较好的数据结构。
用键的hash值来计算的元素的位置
HashMap底层是基于哈希表实现的
HashMap集合是一种增删改查数据,”性能都较好的集合
但是它是无序,不能重复,没有索引支持的(由键决定特点)
HashMap的键依赖hashcode方法和equals方法保证键的唯一
如果键存储的是自定义类型的对象,可以通过重写hashcode和equals方法,这样可以保证多个对象内容一样时,HashMap集合就能认为是重复的。
import java.util.*;
import java.util.function.BiConsumer;
public class MapTest {
public static void main(String[] args) {
Map<Student,String> map =new HashMap<>();
map.put(new Student("蜘蛛精",25,168.5),"盘丝洞");
map.put(new Student( "蜘蛛精",25,168.5),"水帘洞");
map.put(new Student( "至尊宝",23,163.5),"水帘洞");
map.put(new Student( "牛魔王",28,183.5),"牛头山");
System.out.println(map);
}
}
这里可以看出蜘蛛精的键是重复的
{Student{name='蜘蛛精', age=25, height=168.5}=水帘洞, Student{name='牛魔王', age=28, height=183.5}=牛头山, Student{name='蜘蛛精', age=25, height=168.5}=盘丝洞, Student{name='至尊宝', age=23, height=163.5}=水帘洞}
通过重写hashcode和equals方法,这样可以保证多个对象内容一样时,HashMap集合就能自动去重
package com.qianxin.jihekuangjia;
import java.util.Objects;
public class Student implements Comparable<Student>{
private String name;
private int age;
private double height;
@Override
public int compareTo(Student o) {
// 如果认为左边对象大于右边对象返回正整数
// 如果认为左边对象小于右边对象返回负整数
// 如果认为左边对象等于右边对象返回0
// 需求:按照年龄升序排序、
return this.age-o.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 && Double.compare(height, student.height) == 0 && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, height);
}
public Student() {
}
public Student(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
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 double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
}
保证键的唯一
{Student{name='至尊宝', age=23, height=163.5}=水帘洞, Student{name='牛魔王', age=28, height=183.5}=牛头山, Student{name='蜘蛛精', age=25, height=168.5}=水帘洞}
LinkedHashMap (由键决定特点):由键决定的特点:有序、不重复、无索引。
键值会合并成一个entry对象
通过其中键的hash值来算出在集合中的位置
TreeMap (由键决定特点):按照大小默认升序排序、不重复、无索引。
特点:不重复、无索引、可排序(按照键的大小默认升序排序,只能对键排序)
原理:TreeMap跟TreeSet集合的底层原理是一样的,都是基于红黑树实现的排序。
TreeMap集合同样也支持两种方式来指定排序规则
方法一:让类实现Comparable接口,重写比较规则。
使用TreeMap会对下面的集合进行排序,但是键是自定义对象,无法排序,所以报错
public class MapTest {
public static void main(String[] args) {
//Map<String, Integer> map = new HashMap<>();//一行经典代码。按照键 无序,不重复,无索引。
Map<Student,String> map =new TreeMap<>();
map.put(new Student("蜘蛛精",25,168.5),"盘丝洞");
map.put(new Student( "蜘蛛精",25,168.5),"水帘洞");
map.put(new Student( "至尊宝",23,163.5),"水帘洞");
map.put(new Student( "牛魔王",28,183.5),"牛头山");
System.out.println(map);
}
}
如果我们想要实现TreeMap的自定义排序,可以使用Comparable接口 重写CompareTo方法来实现自定义排序
import java.util.Objects;
public class Student implements Comparable<Student>{
private String name;
private int age;
private double height;
@Override
public int compareTo(Student o) {
// 如果认为左边对象大于右边对象返回正整数
// 如果认为左边对象小于右边对象返回负整数
// 如果认为左边对象等于右边对象返回0
// 需求:按照年龄升序排序、
return this.age-o.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 && Double.compare(height, student.height) == 0 && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, height);
}
public Student() {
}
public Student(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
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 double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
}
没有报错,且实现按照年龄升序排列
{Student{name='至尊宝', age=23, height=163.5}=水帘洞, Student{name='蜘蛛精', age=25, height=168.5}=水帘洞, Student{name='牛魔王', age=28, height=183.5}=牛头山}
方法二TreeMap集合有一个有参数构造器,支持创建Comparator比较器对象,以便用来指定比较规则。
创建Comparator比较器对象,实现按照升高降序排列
import java.util.*;
import java.util.function.BiConsumer;
public class MapTest {
public static void main(String[] args) {
//Map<String, Integer> map = new HashMap<>();//一行经典代码。按照键 无序,不重复,无索引。
Map<Student,String> map =new TreeMap<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return Double.compare(o2.getHeight(),o1.getHeight());
}
});
map.put(new Student("蜘蛛精",25,168.5),"盘丝洞");
map.put(new Student( "蜘蛛精",25,168.5),"水帘洞");
map.put(new Student( "至尊宝",23,163.5),"水帘洞");
map.put(new Student( "牛魔王",28,183.5),"牛头山");
System.out.println(map);
}
}
{Student{name='牛魔王', age=28, height=183.5}=牛头山, Student{name='蜘蛛精', age=25, height=168.5}=水帘洞, Student{name='至尊宝', age=23, height=163.5}=水帘洞}
简写Comparator比较器代码
import java.util.*;
import java.util.function.BiConsumer;
public class MapTest {
public static void main(String[] args) {
//Map<String, Integer> map = new HashMap<>();//一行经典代码。按照键 无序,不重复,无索引。
Map<Student,String> map =new TreeMap<>((o1,o2) ->Double.compare(o2.getHeight(),o1.getHeight()));
map.put(new Student("蜘蛛精",25,168.5),"盘丝洞");
map.put(new Student( "蜘蛛精",25,168.5),"水帘洞");
map.put(new Student( "至尊宝",23,163.5),"水帘洞");
map.put(new Student( "牛魔王",28,183.5),"牛头山");
System.out.println(map);
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。