双列集合
特点
1.双列集合一次需要存一对数据,分别是键和值。
2.键和值一一对应,键不能重复,值能重复。
3.键+值这个整体我们称之为键值对或者键值对对象,在java中叫做Entry对象。
Map的常见API
Map是双列集合的顶层接口,它的功能是全部双列集合都可以继承使用的
package MyApi.myMap;
import java.util.HashMap;
import java.util.Map;
public class a01mymapdemo01 {
public static void main(String[] args) {
//1.创建map集合对象
Map<String, String> m = new HashMap<>();
//2.添加元素
//put方法细节:
//添加/覆盖
//在添加数据的时候,如果键不存在,那么直接把键值对对象添加到map集合当中,方法返回null
//在添加数据的时候,如果键是存在的,那么会把原有的键值对对象覆盖,会把覆盖的值进行返回
m.put("郭靖", "黄蓉");
m.put("韦小宝", "沐剑屏");
m.put("尹志平", "小龙女");
//3.打印
//System.out.println(m);
//删除
String remove = m.remove("郭靖");
System.out.println(remove);
//清空
m.clear();
//判断是否包含
boolean key = m.containsKey("郭靖");
System.out.println(key);
//值是否包含
boolean containsValue = m.containsValue("小龙女");
System.out.println(containsValue);
//判断集合是否为空
boolean empty = m.isEmpty();
System.out.println(empty);
//集合的长度
int size = m.size();
System.out.println(size);
}
}
map集合的遍历方式
1.键找值
package MyApi.myMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class a02Mapdemo02 {
public static void main(String[] args) {
//1.创建集合对象
Map<String,String> map=new HashMap<>();
//2.添加元素
map.put("郭靖", "黄蓉");
map.put("韦小宝", "沐剑屏");
map.put("尹志平", "小龙女");
//3.通过键找值
//3.1获取所有的键,把这些键放到一个单列集合当中
Set<String> keys= map.keySet();
//3.2遍历每一个集合,得到每一个键
for (String key : keys) {
System.out.println(key);
//3.3利用map集合中的键获取对应的值
String value = map.get(key);
System.out.println(key+"="+value);
}
}
}
2.键值对
package MyApi.myMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class a03Mapdemo03 {
public static void main(String[] args) {
//1.创建集合对象
Map<String,String> map=new HashMap<>();
//2.添加元素
map.put("郭靖", "黄蓉");
map.put("韦小宝", "沐剑屏");
map.put("尹志平", "小龙女");
//3.通过键值对对象
//3.1获取所有的键值对对象,返回一个set集合
Set<Map.Entry<String, String>> entries = map.entrySet();
//3.2遍历entries这个集合,去得到里面的每一个键值对对象
for (Map.Entry<String, String> entry : entries) {
//3.3利用entry调用get方法获取键和值
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"="+value);
}
}
}
3.Lamdba表达式
package MyApi.myMap;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
public class a04mymapdemo04 {
public static void main(String[] args) {
//1.创建map集合的对象
Map<String,String> map=new HashMap<>();
//2.添加元素
map.put("郭靖", "黄蓉");
map.put("韦小宝", "沐剑屏");
map.put("尹志平", "小龙女");
//3.利用lamabda表达式进行遍历
//底层:
//foreach其实就是利用第二种方式进行遍历,依次得到每一个键和值
//在调用accept方法
map.forEach(new BiConsumer<String, String>() {
@Override
public void accept(String key, String value) {
System.out.println(key+"="+value);
}
});
System.out.println("--------");
map.forEach((String key, String value)-> System.out.println(key+"="+value)
);
}
}
HashMap
1.HashMap是map里面的一个实现类
2.没有额外需要学习的特有方法,直接使用map里面的方法就可以了
3.特点都是由键决定的:无序、不重复、无索引
4.HashMap跟HashSet底层原理一模一样,都是哈希表结构
5.依赖hashCode方法和equals方法保证键的唯一性
6.如果键存储的是自定义对象,需要重写hashCode和equals方法,如果值存储自定义对象,不需要重写hashCode和equals方法。
package MyApi.myMap;
import java.util.HashMap;
import java.util.Set;
public class a05hashmapdemo05 {
public static void main(String[] args) {
//1.创建hashMap对象
HashMap<Student,String> hm=new HashMap<>();
//2.创建三个学生对象
Student s1=new Student("karry",24);
Student s2=new Student("roy",23);
Student s3=new Student("jackson",23);
//3.添加元素
hm.put(s1,"重庆");
hm.put(s2,"重庆");
hm.put(s3,"湖南");
//4.遍历集合
Set<Student> keys= hm.keySet();
for (Student key : keys) {
String value = hm.get(key);
System.out.println(key+"="+value);
}
}
}
package MyApi.myMap;
import java.util.*;
public class a06hashmapdemo06 {
public static void main(String[] args) {
//1.需要先让同学们投票
String[] arr={"a","b","c","d"};
ArrayList<String> list=new ArrayList<>();
Random r=new Random();
for (int i = 0; i < 80; i++) {
int index= r.nextInt(arr.length);
// System.out.println(arr[index]);
list.add(arr[index]);
}
//2.统计
HashMap<String,Integer> hm=new HashMap<>();
for (String name : list) {
if(hm.containsKey(name)){
Integer count = hm.get(name);
count++;
hm.put(name,count);
}else{
hm.put(name,1);
}
}
System.out.println(hm);
//3.求最大值
int max=0;
Set<Map.Entry<String, Integer>> entries = hm.entrySet();
for (Map.Entry<String, Integer> entry : entries) {
Integer value = entry.getValue();
if(value>max) {
max=value;
}
}
System.out.println(max);
//4.判断那个景点和最大值一样,如果一样,打印出来
for (Map.Entry<String, Integer> entry : entries) {
Integer value = entry.getValue();
if(value==max) {
System.out.println(entry.getKey());
}
}
}
}
LinkedHashMap
-
由键决定:有序、不重复、无索引
-
这里的有序是指保证存储和取出的元素顺序一致
-
原理:底层数据结构依然是哈希表,只是每个键值对元素又额外多了一个双链表的机制记录存储的数据
TreeMap
-
treemap和treeset底层原理一样,都是红黑树结构的
-
由键决定特性:不重复、无索引、可排序
-
可排序:对键进行排序
-
注意:默认按照键的大小从小到大进行排序,也可以自己规定键的排序顺序
代码书写两种排序规则
-
实现Comparable接口,指定比较规则
-
创建集合时传递Comparator比较器对象,指定比较规则。
-
如果写的第一种也写了第二种则以第二种为准
package MyApi.myMap; import java.util.Comparator; import java.util.TreeMap; public class a07Treesetdemo07 { public static void main(String[] args) { //1.创建集合对象 TreeMap<Integer,String> tm=new TreeMap<>(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { //o1表示要添加的元素 //o2表示已经在红黑树中存在的元素 return o2-o1; } }); tm.put(1,"奥利奥"); tm.put(2,"康师傅"); tm.put(3,"九个核桃"); tm.put(4,"雷碧"); tm.put(5,"可口可乐"); //3. System.out.println(tm); } }
package MyApi.myMap; 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 i = this.getAge() - o.getAge(); i= i==0?this.getName().compareTo(o.getName()):i; return i; } } package MyApi.myMap; import java.util.TreeMap; public class a08treemapdemo08 { public static void main(String[] args) { TreeMap<Student,String> tm=new TreeMap<>(); Student s1=new Student("karry",24); Student s2=new Student("roy",23); Student s3=new Student("jackson",23); tm.put(s1,"重庆"); tm.put(s2,"重庆"); tm.put(s3,"湖南"); System.out.println(tm); } }
统计个数 package MyApi.myMap; import java.util.TreeMap; import java.util.function.BiConsumer; public class a09treesedemo09 { public static void main(String[] args) { String s="aababcabcbdabcde"; TreeMap<Character,Integer> tm=new TreeMap<>(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if(tm.containsKey(c)){ int count=tm.get(c) ; count++; tm.put(c,count); }else { tm.put(c,1); } } StringBuilder sb=new StringBuilder(); tm.forEach(new BiConsumer<Character, Integer>() { @Override public void accept(Character key, Integer value) { sb.append(key).append("(").append(value).append(")"); } }); System.out.println(sb); } }
-