Map接口【和Collection接口并列】
Map接口
成员方法【实现于Map接口,TreeMap也可实现,这里以HashMap为例】
//HashMap实现类 :无序[HashSet底存原理] 哈希表
public class Demo1 {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
//添加键值对[put方法]
map.put("张三",20);
map.put("李四",20);
//如果键一样,则后面的值会会覆盖前面的值
map.put("张三",40);
map.put("王五",20);
System.out.println(map);
//remove 根据键删除键值对元素,返回删除的键对应的值
Integer value1 = map.remove("张三");
System.out.println(value1);
//clear清空
/*map.clear();
System.out.println(map);*/
//containsKeys判断集合中是否包含指定的键,并返回boolean
boolean result1 = map.containsKey("张三");
boolean result2 = map.containsKey("李四");
System.out.println(result1);
System.out.println(result2);
//containsValue判断集合中是否包含指定的值,并返回boolean
boolean result3 = map.containsValue(20);
boolean result4 = map.containsValue(40);
System.out.println(result3);
System.out.println(result4);
//isEmpty判断集合是否为空,并返回boolean
boolean result5 = map.isEmpty();
System.out.println(result5);
//int size()集合的长度,集合中键值对的个数
System.out.println(map.size());
//keySet获取所有的键
Set<String> keys = map.keySet();
System.out.println(keys);
//get(Key)获取键对应的值
Integer value2 = map.get("张三");
Integer value3 = map.get("李四");
System.out.println(value2);
System.out.println(value3);
//entrySet获取所有的键值对
Set<Map.Entry<String, Integer>> entries = map.entrySet();
System.out.println(entries);
}
}
打印结果:
----------------------------------------------------------------
{李四=20, 张三=40, 王五=20}
40
false
true
true
false
false
2
[李四, 王五]
null
20
[李四=20, 王五=20]
Map集合遍历方法
//遍历HashMap
public class Demo3 {
public static void main(String[] args) {
//创建集合并添加元素
HashMap<String, String> map = new HashMap<>();
map.put("1号丈夫", "1号妻子");
map.put("2号丈夫", "2号妻子");
map.put("3号丈夫", "3号妻子");
map.put("1号丈夫", "1号妻子");
//第一中方法:键找值的方式
//keySet获取所有的键
//返回值为set集合[set为接口,集合类型为其具体的实现类]
Set<String> keys = map.keySet();
for (String key : keys) {
String value = map.get(key);
System.out.println(key + "..." + value);
}
System.out.println("----------------------------");
//第二种方法:获取键值对对象
//entrySet获取所有的键值对对象
// //返回值为set集合[set集合存储的是键值对对象,Entry存储的是键和值]
Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<String,String> entry : entries) {
System.out.println(entry.getKey() + "..." + entry.getValue());
}
}
}
打印结果:
-----------------------------------------------------------------
1号丈夫...1号妻子
2号丈夫...2号妻子
3号丈夫...3号妻子
----------------------------
1号丈夫...1号妻子
2号丈夫...2号妻子
3号丈夫...3号妻子
实现类HashMap
1.特点:无序,双列,键唯一,值可重复,不可排序
2.底层原理:哈希表【链表,数组,[链表满8为]红黑树】
HashMap和HashSet一样底层为哈希表,默认比较为地址值,API有的类已经写好的我们就不需要重写,但我们自定义的类一般都需要重写HashCode方法
a.【HashMap默认比较键的地址值】
//HashMap存储对象
//保证键不重复
public class Demo4 {
public static void main(String[] args) {
HashMap<Student, String> map = new HashMap<>();
Student student1 = new Student("JS", 1800);
Student student2 = new Student("LQ", 2000);
Student student3 = new Student("小汪", 18);
Student student4 = new Student("小汪", 18);
map.put(student1, "兽族");
map.put(student2, "不死族");
map.put(student3,"兽族");
map.put(student4, "牛牛牛");
// public int hashCode() {
// int h = 0;
// for (Entry<K, V> entry : entrySet())
// h += entry.hashCode();
// return h;
// }
Set<Map.Entry<Student, String>> entries = map.entrySet();
for (Map.Entry<Student, String> entry : entries) {
System.out.println(entry.hashCode());
}
//键值对遍历
Set<Map.Entry<Student, String>> entries1 = map.entrySet();
for (Map.Entry<Student, String> entry : entries) {
System.out.println(entry.getKey() + "..." + entry.getValue());
}
}
}
打印结果:
---------------------------------------------------------------
473594216
780099464
189191576
1314561244
Student{name='小汪', age=18}...牛牛牛
Student{name='LQ', age=2000}...不死族
Student{name='JS', age=1800}...兽族
Student{name='小汪', age=18}...兽族
b.【HashMap重写键的equals方法和hashCode方法比较键的属性值】
---------------------测试类代码不变---------------------------
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
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;
if (age != student.age) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
}
打印结果:
--------------------------------------------------------------
14493644
20137578
746797
//键相同的时候,后面键对应的值就会覆盖前面的值
Student{name='小汪', age=18}...牛牛牛
Student{name='LQ', age=2000}...不死族
Student{name='JS', age=1800}...兽族
与HashSet的区别:重写针对的都是HashMap的键,其他步骤一样。
实现类TreeMap
1.特点:无序,双列,键唯一,值可重复,有排序功能
2.底层原理:红黑树
3.需要指定排序规则,API中有一些类已经实现了Comparable接口],给出了默认排序规则,如:Integer:数值大小[升序] String:字典顺序等
底层为红黑树会自动对键排序,需要指定排序顺序,有两种方式指定
1.实现Comparable接口,重写compareTo方法
2.创建比较器Comparator,重写compare方法
与TreeSet的区别:重写针对的都是TreeMap的键,其他步骤一样。