本章主要是将Map体系和Collections工具类一并梳理,之后会重点攻破HashMap底层源码
Map接口
Map的异常形式
- 给定一个键和一个值,你可以将该值存储在一个 Map 对象之后,你可以通过键来访问对应的值。
- 当访问的值不存在的时候,方法就会抛出一个 NoSuchElementException 异常。
- 当对象的类型和 Map 里元素类型不兼容的时候,就会抛出一个 ClassCastException 异常。
- 当在不允许使用 Null 对象的 Map 中使用 Null 对象,会抛出一个 NullPointerException 异常。
- 当尝试修改一个只读的 Map 时,会抛出一个 UnsupportedOperationException 异常。
Map的方法
Map的案例实现
class Student{
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class MapTest {
public static void main(String[] args) {
Map<Integer,Student> map=new HashMap<>();
System.out.println("----put----");
Student s1=new Student("张三",18);
Student s2=new Student("李四",19);
Student s3=new Student("王五",20);
map.put(1,s1);
map.put(2,s2);
map.put(3,s3);
System.out.println(map);
System.out.println("----get----");
System.out.println(map.get(1));
System.out.println("----replace----");
map.replace(1,new Student("孙七",22));
System.out.println(map);
System.out.println("----遍历----");
//1.使用keySet
Set<Integer> set = map.keySet();
for (Integer i : set) {
System.out.println("key="+i+"value="+map.get(i));
}
System.out.println("-----------");
//2.使用entrySet
Set<Map.Entry<Integer, Student>> entrySet = map.entrySet();
for (Map.Entry<Integer, Student> i : entrySet) {
System.out.println("key="+i.getKey()+"value="+i.getValue());
}
System.out.println("----remove----");
map.remove(1);
System.out.println(map);
System.out.println("----containsKey/containsValue----");
System.out.println(map.containsKey(1));
System.out.println(map.containsValue(s2));
}
}
//输出结果:
Student{name='张三', age=18}
----replace----
{1=Student{name='孙七', age=22}, 2=Student{name='李四', age=19}, 3=Student{name='王五', age=20}}
----遍历----
key=1value=Student{name='孙七', age=22}
key=2value=Student{name='李四', age=19}
key=3value=Student{name='王五', age=20}
-----------
key=1value=Student{name='孙七', age=22}
key=2value=Student{name='李四', age=19}
key=3value=Student{name='王五', age=20}
----remove----
{2=Student{name='李四', age=19}, 3=Student{name='王五', age=20}}
----containsKey/containsValue----
false
true
Map接口的实现类
HashMap案例实现
class Student{
String name;
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;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
public class HashMapTest {
public static void main(String[] args) {
//方法和map接口差不多
Hashmap<Integer,Student> map=new HashMap<>();
Student s1=new Student("张三",18);
Student s2=new Student("李四",19);
Student s3=new Student("王五",20);
map.put(1,s1);
map.put(2,s2);
map.put(3,s3);
System.out.println(map);
//之前hashset已经讲过,hashmap先通过hashcode找到相应位置,然后通过equals进行比较
//重写hashcode和equals方法就能通过比较属性值删除元素
map.remove(1,new Student("张三",18));
System.out.println(map);
}
}
//输出结果:
{1=Student{name='张三', age=18}, 2=Student{name='李四', age=19}, 3=Student{name='王五', age=20}}
{2=Student{name='李四', age=19}, 3=Student{name='王五', age=20}}
TreeMap案例实现
class Student{
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class TreeMapTest {
public static void main(String[] args) {
TreeMap<Student,String> treeMap=new TreeMap<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int n1=o1.getAge()-o2.getAge();
int n2=o1.getName().compareTo(o2.getName());
return n1!=0?n1:n2;
}
});
treeMap.put(new Student("zhangsan",23),"1号选手");
treeMap.put(new Student("lisi",19),"2号选手");
treeMap.put(new Student("wangwu",20),"3号选手");
treeMap.put(new Student("sunliu",20),"4号选手");
treeMap.put(new Student("zhaoqi",11),"5号选手");
System.out.println(treeMap);
System.out.println("-----firstKey/lastKey-----");
System.out.println("firstKey:"+treeMap.firstKey());
System.out.println("lastKey:"+treeMap.lastKey());
System.out.println("-----firstEntry/lastEntry-----");
System.out.println("firstEntry:"+treeMap.firstEntry().getKey()+"-"+treeMap.firstEntry().getValue());
System.out.println("lastEntry:"+treeMap.lastEntry().getKey()+"-"+treeMap.lastEntry().getValue());
System.out.println("-----pollFirstEntry/pollLastEntry-----");
System.out.println("pollFirstEntry:"+treeMap.pollFirstEntry());
System.out.println(treeMap);
System.out.println("pollLastEntry:"+treeMap.pollLastEntry());
System.out.println(treeMap);
System.out.println("-----descendingMap-----");
NavigableMap<Student, String> map = treeMap.descendingMap();
System.out.println(map);
}
}
//输出结果:
{Student{name='zhaoqi', age=11}=5号选手, Student{name='lisi', age=19}=2号选手, Student{name='sunliu', age=20}=4号选手, Student{name='wangwu', age=20}=3号选手, Student{name='zhangsan', age=23}=1号选手}
-----firstKey/lastKey-----
firstKey:Student{name='zhaoqi', age=11}
lastKey:Student{name='zhangsan', age=23}
-----firstEntry/lastEntry-----
firstEntry:Student{name='zhaoqi', age=11}-5号选手
lastEntry:Student{name='zhangsan', age=23}-1号选手
-----pollFirstEntry/pollLastEntry-----
pollFirstEntry:Student{name='zhaoqi', age=11}=5号选手
{Student{name='lisi', age=19}=2号选手, Student{name='sunliu', age=20}=4号选手, Student{name='wangwu', age=20}=3号选手, Student{name='zhangsan', age=23}=1号选手}
pollLastEntry:Student{name='zhangsan', age=23}=1号选手
{Student{name='lisi', age=19}=2号选手, Student{name='sunliu', age=20}=4号选手, Student{name='wangwu', age=20}=3号选手}
-----descendingMap-----
{Student{name='wangwu', age=20}=3号选手, Student{name='sunliu', age=20}=4号选手, Student{name='lisi', age=19}=2号选手}
Collections工具类
排序操作
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(3);
list.add(-2);
list.add(9);
list.add(5);
list.add(-1);
list.add(6);
//输出:[3, -2, 9, 5, -1, 6]
System.out.println(list);
//集合元素的次序反转
Collections.reverse(list);
//输出:[6, -1, 5, 9, -2, 3]
System.out.println(list);
//排序:按照升序排序
Collections.sort(list);
//[-2, -1, 3, 5, 6, 9]
System.out.println(list);
//根据下标进行交换
Collections.swap(list, 2, 5);
//输出:[-2, -1, 9, 5, 6, 3]
System.out.println(list);
//后两个整体移动到前边
Collections.rotate(list, 2);
//输出:[6, 3, -2, -1, 9, 5]
System.out.println(list);
//随机排序
Collections.shuffle(list);
//每次输出的次序不固定
System.out.println(list);
}
查找替换操作
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(3);
list.add(-2);
list.add(9);
list.add(5);
list.add(-1);
list.add(6);
//[3, -2, 9, 5, -1, 6]
System.out.println(list);
//输出最大元素9
System.out.println(Collections.max(list));
//输出最小元素:-2
System.out.println(Collections.min(list));
//将list中的-2用1来代替
System.out.println(Collections.replaceAll(list, -2, 1));
//[3, 1, 9, 5, -1, 6]
System.out.println(list);
list.add(9);
//判断9在集合中出现的次数,返回2
System.out.println(Collections.frequency(list, 9));
//对集合进行排序
Collections.sort(list);
//[-1, 1, 3, 5, 6, 9, 9]
System.out.println(list);
//只有排序后的List集合才可用二分法查询,输出2
System.out.println(Collections.binarySearch(list, 3));
}
设置不可变集合
public static void main(String[] args) {
//创建一个空的、不可改变的List对象
List<String> unmodifiableList = Collections.emptyList();
//unmodifiableList.add("java");
//添加出现异常:java.lang.UnsupportedOperationException
System.out.println(unmodifiableList);// []
//创建一个只有一个元素,且不可改变的Set对象
Set unmodifiableSet = Collections.singleton("java");
//[java]
System.out.println(unmodifiableSet);
//创建一个普通Map对象
Map scores = new HashMap();
scores.put("语文" , 80);
scores.put("Java" , 82);
//返回普通Map对象对应的不可变版本
Map unmodifiableMap = Collections.unmodifiableMap(scores);
//下面任意一行代码都将引发UnsupportedOperationException异常
//unmodifiableList.add("Hello");
//unmodifiableSet.add("Hello");
//unmodifiableMap.put("Hello",1);
}
Hi, welcome to JasperのBlog!