集合一图流(图片 from 黑马程序员):
一、 Collection
JDK 不提供此接口的任何直接实现,只提供更具体的子接口(Set 和 List)实现。
特点:存储空间可变
1.1 Collection 集合的常用操作
包括添加、删除、判断是否存在指定元素、判空、求长度、清空:
import java.util.ArrayList;
import java.util.Collection;
public class Main {
public static void main(String[] args) {
//创建Collection集合的对象
Collection<String> c = new ArrayList<String>();
//添加元素
c.add("Hello");
c.add("World");
c.add("java");
System.out.println(c); //[Hello, World, java]
//删除
c.remove("java");
System.out.println(c); //[Hello, World]
//判断集合中是否存在指定元素
System.out.println(c.contains("Hello")); //true
System.out.println(c.contains("HelloHello")); //false
//判断集合是否为空
System.out.println(c.isEmpty()); //false
//集合长度
System.out.println(c.size()); //里面有Hello和World两个元素,java已被删除
//清空
c.clear();
System.out.println(c); //[]
}
}
判断 add() 方法是否添加成功:
System.out.println(c.add("javaee"));
在 ArrayList 中可以看到,add() 方法永远都会添加成功,返回 true:
public boolean add(E e) {
modCount++;
add(e, elementData, size);
return true;
}
与之对应的就是 remove() 方法可能会出现 false(查找不到要删除的对象):
public boolean remove(Object o) {
final Object[] es = elementData;
final int size = this.size;
int i = 0;
found: {
if (o == null) {
for (; i < size; i++)
if (es[i] == null)
break found;
} else {
for (; i < size; i++)
if (o.equals(es[i]))
break found;
}
return false;
}
fastRemove(es, i);
return true;
}
1.2 Collection 集合的遍历
Iterator:迭代器,集合的专用遍历方式。
迭代器是通过集合的 iterator() 方法得到的,所以说它是依赖于集合而存在的。
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
//创建集合对象
Collection<String> c = new ArrayList<String>();
//添加元素
c.add("Hello");
c.add("World");
c.add("java");
//迭代器:通过集合对象的iterator()方法得到迭代器对象,返回集合中的元素
Iterator<String> it = c.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
输出结果:
Hello
World
java
1.3 案例:Collection 集合存储学生对象并遍历
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
//创建Collection集合对象
Collection<Student> c = new ArrayList<Student>();
//创建学生对象
Student s1 = new Student("张三",18);
Student s2 = new Student("李四",19);
Student s3 = new Student("王五",16);
//添加学生
c.add(s1);
c.add(s2);
c.add(s3);
//遍历集合,迭代器方式
Iterator<Student> it = c.iterator();
while (it.hasNext()){
Student s = it.next();
System.out.println(s.getName() + ":" + s.getAge());
}
}
}
二、 List
有序集合,用户可以精确控制列表中每个元素的插入位置,通过整数索引访问该元素,并搜索列表中的元素。
- 继承自 Collection 接口,所以 Collection 中的方法 List 都可以使用。
特点:有序(指存储和取出的元素顺序一致)、可重复(存储的元素可以重复,区别于 Set)
2.1 List 集合的基本操作(同 Collection)
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Main {
public static void main(String[] args) {
//创建集合对象
List<String> list = new ArrayList<String>();
//添加集合元素
list.add("Hello");
list.add("World");
list.add("java");
//迭代器方式遍历
Iterator<String> it = list.iterator();
while (it.hasNext()){
String s = it.next();
System.out.println(s);
}
}
}
2.2 List 集合特有方法
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
//创建集合对象
List<String> list = new ArrayList<String>();
//添加元素
list.add("Hello");
list.add("World");
list.add("java");
System.out.println(list); //[Hello, World, java]
//在指定索引位置插入元素,不要越界!
list.add(2,"javaee");
System.out.println(list); //[Hello, World, javaee, java]
//删除指定索引位置元素,不要越界!
list.remove(3);
System.out.println(list); //[Hello, World, javaee]
//修改指定索引位置的元素,返回被修改的元素,不要越界!
System.out.println(list.set(0,"Hi")); //Hello(返回被修改的元素Hello)
System.out.println(list); //[Hi, World, javaee]
//获取指定索引位置元素,不要越界!
System.out.println(list.get(1)); //World
//遍历集合元素
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
System.out.println(s); //Hi\n World\n javaee
}
}
}
2.3 案例:List 集合存储学生对象并遍历
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Main {
public static void main(String[] args) {
//创建List集合对象
List<Student> list = new ArrayList<Student>();
//创建学生对象3
Student s1 = new Student("张三",18);
Student s2 = new Student("李四",19);
Student s3 = new Student("王五",16);
//把学生添加到集合
list.add(s1);
list.add(s2);
list.add(s3);
//遍历集合,迭代器Iterator方式
Iterator<Student> it = list.iterator();
while (it.hasNext()){
Student s = it.next();
System.out.println(s.getName() + ":" + s.getAge());
}
//for循环方式
for (int i = 0; i < list.size(); i++) {
Student s = list.get(i);
System.out.println(s.getName() + ":" + s.getAge());
}
}
}
2.4 ListIterator
ListIterator:列表迭代器
- 运行 List 集合的 listIterator() 方法得到,是 List 集合特有的迭代器。
- 允许眼任一方向遍历列表,在迭代期间修改列表,并获取列表中迭代器的当前位置。
ListIterator 中的常用方法(正向遍历、逆向遍历、添加元素等):
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class Main {
public static void main(String[] args) {
//创建集合对象
List<String> list = new ArrayList<String>();
//添加元素
list.add("Hello");
list.add("World");
list.add("java");
System.out.println(list); //[Hello, World, java]
ListIterator<String> lit = list.listIterator();
//正向遍历
while (lit.hasNext()){
String s = lit.next();
System.out.println(s); //Hello World java
}
//逆向遍历
while (lit.hasPrevious()){
String s = lit.previous();
System.out.println(s); //java World Hello
}
//获取列表迭代器
while (lit.hasNext()){
String s = lit.next();
if (s.equals("World")){
lit.add("javaee"); //添加在World之后
}
}
System.out.println(list); //[Hello, World, javaee, java]
}
}
2.5 增强 for 循环
增强 for:简化数组和 Collection 集合的遍历。其内部原理就是 Iterator 迭代器。
格式:
for(元素数据类型 变量名:数组或者 Collection 集合){
//此处使用变量即可,该变量就是元素
}
例:
int arr[] = {1, 2, 3, 4, 5};
for(int i:arr){
System.out.println(i);
}
简单操作:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
//遍历整型数组
int[] a = {1,2,3,4,5};
for (int i:a){
System.out.println(i); //1 2 3 4 5
}
//遍历字符串数组
String[] strings = {"Hello","World","java"};
for (String str:strings){
System.out.println(str); //Hello World java
}
//遍历列表
List<String> list = new ArrayList<String>();
list.add("Hello");
list.add("World");
list.add("java");
for (String s:list){
System.out.println(s); //Hello World java
}
}
}
2.6 List 集合子类特点
List 集合常用子类:ArrayList,LinkedList
- ArrayList:底层数据结构是数组,查询快,增删慢。
- LinkedList:底层数据结构是链表,查询慢,增删块。
基本操作与 List 相同,简单列一下:
import java.util.ArrayList;
import java.util.LinkedList;
public class Main {
public static void main(String[] args) {
//创建集合对象
ArrayList<String> array = new ArrayList<String>();
//添加集合元素
array.add("Hello");
array.add("World");
array.add("java");
//遍历
for (String s: array) {
System.out.println(s);
}
//创建集合对象
LinkedList<String> linkedList = new LinkedList<String>();
//添加集合元素
linkedList.add("Hello");
linkedList.add("World");
linkedList.add("java");
//遍历
for (String s: linkedList) {
System.out.println(s);
}
}
}
2.7 LinkedList 集合特有方法
因为 LinkedList 底层数据结构是链表,所以有一些特有的与链表有关的方法。
import java.util.LinkedList;
public class Main {
public static void main(String[] args) {
//创建集合对象
LinkedList<String> linkedList = new LinkedList<String>();
//添加集合元素
linkedList.add("Hello");
linkedList.add("World");
linkedList.add("java");
linkedList.add("javaee");
System.out.println(linkedList.getFirst()); //返回此列表中的第一个元素 Hello
System.out.println(linkedList.getLast()); //返回此列表中的最后一个元素 javaee
System.out.println(linkedList.removeFirst()); //删除并返回第一个元素 Hello
System.out.println(linkedList.removeLast()); //删除并返回最后一个元素 javaee
System.out.println(linkedList); //[World, java]
}
}
三、 Set
3.1 Set 集合概述和特点
Set 集合特点:
- 不包含重复的元素
- 没有带索引的方法,所以不能使用普通的 for 循环遍历(但可以使用增强 for 或者迭代器 Iterator)
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
//创建集合对象
Set<String > set = new HashSet<String>();
//添加元素
set.add("Hello");
set.add("World");
set.add("java");
set.add("World");
//遍历
for (String s:set) {
System.out.println(s); //java Hello World
}
}
}
输出结果解释:
Set 集合不包含重复元素,所以只能传入一个 World,而且 Set 集合对集合的迭代顺序不做任何保证(内部靠哈希值存储),所以输出顺序并非存入顺序。
3.2 哈希值
哈希值:是 JDK 根据对象的地址或字符串或数字算出来的 int 类型的数值。
Object类中获取对象哈希值的方法:
public int hashCode() //返回对象的哈希码值
对象哈希值的特点:
- 同一个对象多次调用 hashCode() 方法返回的哈希值是相同的。
- 一般情况下,不同对象的哈希值是不同的。重写 hashCode() 方法,可以实现让不同对象的哈希值相同。
重点:
- 如果两个对象相等,则 hashCode 一定相同。
- 两个对象拥有相同的 hashCode 值,它们也不一定是相等的。在此情况下就要使用 equals() 方法,判断这两个 hashCode 值相等的对象是否真的相同。
public class Main {
public static void main(String[] args) {
//创建学生类对象
Student s1 = new Student("张三",18);
Student s2 = new Student("李四",19);
Student s3 = new Student("王五",20);
//同一个对象多次调用hashCode()方法返回的哈希值是相同的
System.out.println(s1.hashCode()); //2129789493
System.out.println(s1.hashCode()); //2129789493
//不同对象的哈希值几乎是不同的
System.out.println(s2.hashCode()); //668386784
System.out.println(s3.hashCode()); //1329552164
//特殊情况下,哈希值可能会相同
System.out.println("重地".hashCode()); //1179395
System.out.println("通话".hashCode()); //1179395
}
}
3.3 HashSet 集合概述和特点
特点:
- 底层数据结构是哈希表。
- 对集合的迭代顺序不做任何保证,即不保证存储和取出数据的一致。
- 没有带索引的方法,不能使用普通 for 循环遍历。
- 由于是 Set 集合,所以不包含重复元素。
基本操作与3.2类似, 不列了!摸了!
3.4 常见数据结构之哈希表
3.5 案例:HashSet 集合存储学生对象并遍历
重点:
不同对象的定义: new 出来的都是新对象,哪怕里面的数据是相同的。例如 s3 和 s4,虽然里面数据相同,但是是 Student 类实例化的两个对象,其哈希码值是不同的!
所以要重写 hashCode() 和 equals() 方法!(自动重写即可)
Main 类:
import java.util.HashSet;
public class Main {
public static void main(String[] args) {
//创建集合对象
HashSet<Student> hs = new HashSet<Student>();
//创建学生对象
Student s1 = new Student("张三",18);
Student s2 = new Student("李四",19);
Student s3 = new Student("王五",16);
Student s4 = new Student("王五",16);
//把学号是哪个添加到集合
hs.add(s1);
hs.add(s2);
hs.add(s3);
hs.add(s4);
//遍历集合
for(Student s : hs){
System.out.println(s.getName() + ":" + s.getAge());
}
}
}
Student 类:
import java.util.Objects;
public class 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 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);
}
}
输出结果:
王五:16
张三:18
李四:19
3.6 LinkedHashSet
特点:
- 由哈希表和链表实现的 Set 接口,具有可预测的迭代顺序(可以用普通 for 循环)。
- 由链表保证元素有序,即元素的存储和取出顺序是一致的。
- 由哈希表保障元素唯一,即不存在重复的元素。
简单操作:
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args) {
//创建集合对象
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>();
//添加元素
linkedHashSet.add("Hello");
linkedHashSet.add("World");
linkedHashSet.add("java");
for (String s: linkedHashSet) {
System.out.println(s);
}
}
}
3.7 TreeSet 集合概述和特点
特点:
- 元素有序。这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体的排序方式取决于构造方法。
① TreeSet():根据其元素的自然顺序进行排序。
② TreeSet(Comparator comparator):根据指定的比较器进行排序。 - 没有带索引的方法,所以不能使用普通的 for 循环遍历。
- 由于是 Set 集合,所以是不包含重复元素的集合。
代码摸了!反正都差不多!
3.8 自然排序 Comparable
是个接口!该接口对实现它的每个类的对象加一个整体排序。这个排序被称为自然排序,类的 compareTo() 方法被称为自然比较方法。
compareTo() 方法:就是我们要去重写的方法,重写它改变排序!
return 0:表示重复元素(只存入第一个数据,其他的不添加)。
return 正数:表示后一个数比前一个数大,放在前一个数后面。
return 负数:表示后一个数比前一个数小,放在前一个数前面。
直接上案例!
Main类:
import java.util.TreeSet;
public class Main {
public static void main(String[] args) {
//创建集合对象
TreeSet<Student> ts = new TreeSet<Student>();
//创建学生类
Student s1 = new Student("张三",18);
Student s2 = new Student("李四",19);
Student s3 = new Student("王五",16);
Student s4 = new Student("赵二",14);
//添加到集合
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
for (Student s: ts) {
System.out.println(s.getName() + ":" + s.getAge());
}
}
}
Student 类:
注意实现了 Comparable 接口与重写了 compareTo() 方法!
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 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 s) {
return this.age - s.age; //现有的数是this.age,要比较的数是s.age
}
}
关于重写 compareTo() 方法的理解:
public int compareTo(Student s) {
return this.age - s.age; //现有的数是this.age,要比较的数是s.age
}
this 代表接下来要存储的元素,s 代表 TreeSet 中已经存储的元素。this(新元素)与 s(原来的元素)相减,如果是负数,表示this(新元素)比 s(原来的元素)小,放在 s(原来的元素)之前;如果是正数,表示 this(新元素)比 s(原来的元素)大,放在 s(原来的元素)之后。
3.9 比较器排序 Comparator 的使用
使用了匿名内部类!!!
Main 类:
import java.util.Comparator;
import java.util.TreeSet;
public class Main {
public static void main(String[] args) {
//创建集合对象
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() { //匿名内部类
@Override
public int compare(Student s1, Student s2) { //s1:新传进来的,s2原先里面的
//this.age - s.age
// s1 - s2
int num = s1.getAge() - s2.getAge();
//先安装年龄升序排序,年龄相同按照名字升序排序
int num2 = num==0 ? s1.getName().compareTo(s2.getName()) : num;
return num2;
}
});
//创建学生类
Student s1 = new Student("张三",19);
Student s2 = new Student("李四",18);
Student s3 = new Student("王五",16);
Student s4 = new Student("赵二",14);
//添加到集合
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
for (Student s: ts) {
System.out.println(s.getName() + ":" + s.getAge());
}
}
}
Student 类:
import java.util.Objects;
public class 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;
}
}
输出结果:
赵二:14
王五:16
李四:18
张三:19
结论:
- 用 TreeSet 集合存储自定义对象,带参构造方法使用的是比较器 Comparator 排序。
- 比较器排序,就是让集合构造方法接收 Comparator 的实现类对象,重写 compare(T o1, T o2) 方法。
- 重写方法时,要注意排序规则必须按照要求的主要条件和次要条件来写。
3.10 案例:产生不同的随机数
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class Main {
public static void main(String[] args) {
//创建集合对象
Set<Integer> set = new HashSet<Integer>();
//创建随机数对象
Random r = new Random();
while (set.size() < 10){
int number = r.nextInt(20) + 1; //随机数范围为0-19,所以要+1
set.add(number);
}
//遍历集合并输出
for (Integer i:set) {
System.out.println(i);
}
}
}
四、 泛型
4.1 泛型概述
泛型本质是参数化类型,即所操作的数据类型被指定为一个参数。
参数化类型:将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型。
泛型定义格式:
- <类型>:指定一种类型的格式,这里的类型可以看成是形参。
- <类型1,类型2>:指定多种类型的格式,多种类型之间用逗号隔开,这里的类型可以看成是形参。
具体调用的时候给定的类型可以看成是实参,并且实参的类型之能事引用数据类型。
泛型的好处:
- 把运行时期的问题提前到了编译期间。
- 避免了强制类型转换。
4.2 泛型类
泛型类的定义格式:
- 格式:修饰符 class 类名 < 类型 > { }
- 范例:public class Generic < T > { }
Application 类:
public class Application {
public static void main(String[] args) {
Generic<String> g1 = new Generic<String>();
g1.setT("张三");
System.out.println(g1.getT());
Generic<Integer> g2 = new Generic<Integer>();
g2.setT(28);
System.out.println(g2.getT());
}
}
Generic 类:
public class Generic<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
Student 类:
public class Student {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Teacher 类:
public class Teacher {
private Integer age;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
4.3 泛型方法
在没有使用泛型方法/泛型类之前,我们通常使用方法重载来完成同一方法不同参数的实现。
泛型方法的定义格式:
- 格式:修饰符 < 类型 > 返回值类型 方法名(类型 变量名){ }
- 范例:public < T > void show (T t) { }
Application 类:
public class Application {
public static void main(String[] args) {
Generic g1 = new Generic();
g1.show("张三");
g1.show(18);
g1.show(true);
}
}
Generic 类(实现方法重载):
public class Generic {
public void show(String s){
System.out.println(s);
}
public void show(Integer i){
System.out.println(i);
}
public void show(Boolean b){
System.out.println(b);
}
}
使用泛型类改进:
Application 类:
public class Application {
public static void main(String[] args) {
Generic<String> g1 = new Generic<String>();
g1.show("张三");
Generic<Integer> g2 = new Generic<Integer>();
g2.show(18);
Generic<Boolean> g3 = new Generic<Boolean>();
g3.show(true);
}
}
Generic 类:
public class Generic<T> {
public void show(T t){
System.out.println(t);
}
}
可以看到,Generic 类简单了许多。但是在 Application 类中每次创建对象时都要明确数据类型,过于麻烦,所以可以使用泛型方法进行改进:
Application 类:
public class Application {
public static void main(String[] args) {
Generic g1 = new Generic();
g1.show("张三");
g1.show(18);
g1.show(true);
g1.show(0.618);
}
}
Generic 类:
public class Generic {
public <T> void show(T t){
System.out.println(t);
}
}
4.4 泛型接口
定义格式:
- 格式:修饰符 interface 接口名 < 类型 > { }
- 范例:public interface Generic < T > { }
Application 类:
import Genericity.Demo01.Generic;
public class Application {
public static void main(String[] args) {
GenericInterface<String> g1 = new GenericImplement<String>();
g1.show("张三");
GenericInterface<Integer> g2 = new GenericImplement<Integer>();
g2.show(18);
GenericInterface<Double> g3 = new GenericImplement<Double>();
g3.show(0.618);
}
}
Interface 接口(只有抽象方法,没有具体实现):
public interface GenericInterface<T> {
void show(T t);
}
Implement 重写方法实现接口:
public class GenericImplement<T> implements GenericInterface<T>{
@Override
public void show(T t) {
System.out.println(t);
}
}
4.5 类型通配符
类型通配符 < ? >
- 类型通配符上限:< ? extends 类型 >
- List < ? extends Number >:表示的类型是 Number 或者其子类型
- 类型通配符下限:< ? super 类型 >
- List < ? super Number >:表示的类型是 Number 或者其父类型
4.6 可变参数
- 格式:修饰符 返回值类型 方法名(数据类型… 变量名){ }
- 范例:public static int sum ( int… a ) { }
注:若函数要输入多个参数,可变参数要放在最后!
public class Main {
public static void main(String[] args) {
System.out.println(sum(1,2,3,4,5));
System.out.println(sum(2,5,6,8));
System.out.println(sum(10,1,16,80,66,27,41,55));
}
public static int sum(int... a){
int sum = 0;
for (int i : a){
sum = sum + i;
}
return sum;
}
}
五、Map
5.1 Map 集合的概述
Map 集合概述:
- Interface Map < K,V >,K:key,键的类型;V:value,值的类型。
- 将键映射到值的对象;不能包含重复的键;每个键可以映射到最多一个值。
5.2 Map 集合的基本功能
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
//创建集合对象
Map<String,String> map = new HashMap<String,String>();
//添加元素
map.put("Hello","World");
map.put("hello","world");
map.put("java","javaee");
//输出集合对象
System.out.println(map); //{java=javaee, Hello=World, hello=world}
//删除元素,返回被删除key对应的value
System.out.println(map.remove("hello")); //world
System.out.println(map.remove("python")); //null
//判断集合是否包括指定的键or值
System.out.println(map.containsKey("java")); //true
System.out.println(map.containsValue("python")); //false
//判断集合是否为空
System.out.println(map.isEmpty()); //false
//集合的长度
System.out.println(map.size()); //2
}
}
5.3 Map 集合的获取功能
包括:根据 key 获取 value,获取所有 key,获取所有 value。
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
//添加元素
map.put("Hello","World");
map.put("hello","world");
map.put("java","javaee");
//根据键获取值
System.out.println(map.get("Hello")); //World
System.out.println(map.get("python")); //null
//获取所有的键
Set<String> set = map.keySet();
for (String s: set){
System.out.println(s); //java Hello hello 注意:Set集合是无序的
}
//获取所有的值
Collection<String> values = map.values();
for (String s: values){
System.out.println(s); //javaee World world
}
}
}
5.4 Map 集合的遍历(一)
思路:
- 获取所有 key 的集合。用 keySet() 方法实现。
- 遍历 key 的集合,获取到每一个 key。用增强 for 实现。
- 根据 key 寻找 value。用 get (Object key) 方法实现。
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Main {
public static void main(String[] args) {
//创建集合对象
Map<String,String> map = new HashMap<String,String>();
//添加元素
map.put("Hello","World");
map.put("hello","world");
map.put("java","javaee");
//获取所有键的集合
Set<String> set = map.keySet();
//遍历键的集合
for (String key : set){
//根据键寻找值
String value = map.get(key);
System.out.println(key + "," + value);
}
}
}
5.5 Map 集合的遍历(二)
思路:
- 获取所有键值对对象的集合:
Set < Map.Entry<K,V> > entrySet(): //获取所有键值对对象的集合
- 遍历键值对对象的集合,得到每一个键值对对象
用增强 for 实现,得到每一个 Map.Entry。 - 根据键值对对象获取键和值:
用 getKey() 方法得到键;用 getValue() 方法得到值。
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Demo04 {
public static void main(String[] args) {
//创建集合对象
Map<String,String> map = new HashMap<String,String>();
//添加元素
map.put("Hello","World");
map.put("hello","world");
map.put("java","javaee");
//获取所有键值对对象的集合
Set<Map.Entry<String, String>> entries = map.entrySet();
//遍历键值对对象的集合,得到每一个键值对对象
for (Map.Entry<String, String> me: entries){ //Map.Entry<String, String>就是个元素类型
String key = me.getKey();
String value = me.getValue();
}
}
}
5.6 案例:HashMap 集合存储学生对象并遍历
Application 类:
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Application {
public static void main(String[] args) {
//创建HashMap集合对象
HashMap<String,Student> hm = new HashMap<String,Student>();
//创建学生类
Student s1 = new Student("张三",18);
Student s2 = new Student("李四",20);
Student s3 = new Student("王五",16);
Student s4 = new Student("赵二",14);
//把学生添加进集合
hm.put("001",s1);
hm.put("002",s2);
hm.put("003",s3);
hm.put("004",s4);
//法一:通过键寻找值
Set<String> set = hm.keySet(); //获取键的Set集合
for (String key:set){
Student value = hm.get(key);
System.out.println(key + "," + value.getName() + "," + value.getAge());
}
System.out.println("--------");
//法二:通过键值对对象寻找键和值
Set<Map.Entry<String, Student>> entrySet = hm.entrySet();
for (Map.Entry<String, Student> me:entrySet){
String key = me.getKey();
Student value = me.getValue();
System.out.println(key + "," + value.getName() + "," + value.getAge());
}
}
}
Student 类:
public class Student {
private String name;
private int age;
public Student(){
}
public Student(String name, int age){
this.age = age;
this.name = name;
}
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;
}
}
输出结果:
001,张三,18
002,李四,20
003,王五,16
004,赵二,14
--------
001,张三,18
002,李四,20
003,王五,16
004,赵二,14
后记:
差不多基础知识就是这样啦!还有一些集合的嵌套就咕咕咕啦(说不定那天回来部了呢?)如果后续发现有新知识或者写错的会回来修改的!
路还很长很长,继续努力!