文章目录- 集合
- (一)集合基础
- 1.集合概述
- 2.ArrayList构造方法和添加方法
- 3.ArrayList集合常用方法
- 4.遍历集合的通用格式
- (二)Collection
- 1.集合类体系结构
- 2.Collection集合概述和使用
- 3.Collection集合常用方法
- 4.Collection集合的遍历
- 5.集合的使用步骤
- 6.案例(Collection集合存储学生对象并遍历)
- (三)List集合
- 1.List集合概述和特点
- 2.List集合特有方法
- 3.案例(List集合存储学生对象并遍历)
- 4.并发修改异常
- 5.ListIterator列表迭代器
- 6.增强for循环
- 7.案例(List集合存储学生对象用三种方式遍历)
- 8.List 集合子类特点
- 9.案例(分别使用ArrayList和LinkedList完成存储字符串并遍历)
- 10.LinkedList集合的特有功能
- (四)Set集合
- 1.Set集合概述和特点
- 2.哈希值
- 3.HashSet集合概述和特点
- 4.HashSet集合保证元素唯一性源码分析
- 5.案例(HashSet集合存储学生对象并遍历)
- 6.LinkedHashSet集合概述和特点
- 7.TreeSet集合概述和特点
- 8.自然排序Comparable的使用
- 9.比较器排序Comparator的使用
- 10.案例(不重复的随机数)
- (五)Map集合
- 1.Map集合概述和使用
- 2.Map集合的基本功能
- 3.Map集合的获取功能
- 4.Map集合的遍历
- (1)方式一
- (2)方式二
- 5.案例(HashMap嵌套ArrayList)
- 6.统计字符串中每个字符出现的次数
- (六)Collections工具类
- 1.Collections概述和使用
- (一)集合基础
- 1.集合概述
- 2.ArrayList构造方法和添加方法
- 3.ArrayList集合常用方法
- 4.遍历集合的通用格式
- (二)Collection
- 1.集合类体系结构
- 2.Collection集合概述和使用
- 3.Collection集合常用方法
- 4.Collection集合的遍历
- 5.集合的使用步骤
- 6.案例(Collection集合存储学生对象并遍历)
- (三)List集合
- 1.List集合概述和特点
- 2.List集合特有方法
- 3.案例(List集合存储学生对象并遍历)
- 4.并发修改异常
- 5.ListIterator列表迭代器
- 6.增强for循环
- 7.案例(List集合存储学生对象用三种方式遍历)
- 8.List 集合子类特点
- 9.案例(分别使用ArrayList和LinkedList完成存储字符串并遍历)
- 10.LinkedList集合的特有功能
- (四)Set集合
- 1.Set集合概述和特点
- 2.哈希值
- 3.HashSet集合概述和特点
- 4.HashSet集合保证元素唯一性源码分析
- 5.案例(HashSet集合存储学生对象并遍历)
- 6.LinkedHashSet集合概述和特点
- 7.TreeSet集合概述和特点
- 8.自然排序Comparable的使用
- 9.比较器排序Comparator的使用
- 10.案例(不重复的随机数)
- (五)Map集合
- 1.Map集合概述和使用
- 2.Map集合的基本功能
- 3.Map集合的获取功能
- 4.Map集合的遍历
- (1)方式一
- (2)方式二
- 5.案例(HashMap嵌套ArrayList)
- 6.统计字符串中每个字符出现的次数
- (六)Collections工具类
- 1.Collections概述和使用
集合
(一)集合基础
1.集合概述
集合类的特点:提供一种存储空间可变的存储模型,存储的数据容量可以发生改变
集合类有很多种,ArrayList是其中的一种
ArrayList:
- 可调整大小的数组实现
- :是一种特殊的数据类型,泛型
如何用?
- 在出现E的地方使用引用数据类型替换即可
- 举例:ArrayList,ArrayList
2.ArrayList构造方法和添加方法
- public ArrayList() 创建一个空的集合对象
- public boolean add(E e) 将指定的元素追加到此集合的末尾(因为调用这个方法的返回值是boolean类型,也就是调用完毕后会返回一个true或者false)
- public void add(int index,E element) 在此集合中的指定位置插入指定的元素
代码演示:
代码语言:javascript复制// public boolean add(E e)
ArrayList<String> array = new ArrayList<>();
array.add("hello");
array.add("Java");
System.out.println(array); //[hello, Java]
System.out.println(array.add("world")); // true
// public void add(int index,E element)
array.add(1,"Javase");
System.out.println(array); // [hello, Javase, Java]
array.add(4,"1111"); //IndexOutOfBoundsException(索引越界)
3.ArrayList集合常用方法
- public boolean remove(Object to) 删除指定的元素,返回删除是否成功
- public E remove(int index) 删除指定索引处的元素,返回被删除的元素
- public E set(int index,E element) 修改指定索引处的元素,返回被修改的元素
- public E get(int index) 返回指定索引处的元素
- public int size() 返回集合中的元素个数
代码演示:
代码语言:javascript复制// public boolean remove(Object to) 返回删除是否成功
System.out.println(array.remove("Javase")); //true
System.out.println(array.remove("111")); //false
// public E remove(int index) 返回被删除的元素
System.out.println(array.remove(1)); //Java
// public E set(int index,E element) 返回被修改的元素
System.out.println(array.set(0,"hello1")); //hello
// public E get(int index) 返回指定索引处的元素
System.out.println(array.get(0)); //hello1
// public int size() 返回集合中元素的个数
System.out.println(array.size()); //1
4.遍历集合的通用格式
代码语言:javascript复制ArrayList<String> array = new ArrayList<>();
array.add("hello");
array.add("java");
array.add("world");
// 遍历集合的通用格式
for (int i = 0; i < array.size(); i ) {
String s = array.get(i);
System.out.println(s);
}
(二)Collection
1.集合类体系结构
2.Collection集合概述和使用
Collection集合概述
- 是单例集合的顶层接口,他表示一组对象,这些对象也称为Collection的元素
- JDK不提供此接口的任何直接实现,它提供更具体的子接口(如set和List)实现
创建Collection集合的对象
- 多态的方式
- 具体的实现类ArrayList
代码演示:
代码语言:javascript复制import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo {
public static void main(String[] args) {
//创建Collection集合对象
Collection<String> c = new ArrayList<>();
//添加元素:boolean add(E e)
c.add("hello");
c.add("world");
c.add("java");
//输出集合对象
System.out.println(c);// [hello, world, java]
}
}
3.Collection集合常用方法
4.Collection集合的遍历
Iterator:迭代器,集合的专用遍历格式
- Iterator iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到
- 迭代器是通过集合的iterator()方法得到的,所以我们说它是依赖于集合而存在的
Iterator中的常用方法
- E next():返回迭代中的下一个元素
- boolean hasNext():如果迭代具有更多元素,则返回true
代码演示:
代码语言:javascript复制import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo {
public static void main(String[] args) {
//创建Collection集合对象
Collection<String> c = new ArrayList<>();
c.add("hello");
c.add("world");
c.add("java");
System.out.println(c); //[hello, world, java]
//通过集合的 Iterator<E> iterator()方法获得迭代器对象
Iterator<String> i = c.iterator();//多态的方式获得对象 (在iterator方法里返回了实现类对象)
//用while循环遍历集合
while(i.hasNext()){
String s = i.next();
System.out.println(s);
}
}
}
/*
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
......
}
*/
5.集合的使用步骤
6.案例(Collection集合存储学生对象并遍历)
代码实现:
创建学生类(Student):
代码语言:javascript复制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;
}
}
创建测试类(StudentDemo):
代码语言:javascript复制import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class StudentDemo {
public static void main(String[] args) {
//创建集合对象
Collection<Student> c = new ArrayList<>();
//创建三个学生对象
Student s1 = new Student("学生1",20);
Student s2 = new Student("学生2",21);
Student s3 = new Student("学生3",22);
//将学生对象添加进集合中存储
c.add(s1);
c.add(s2);
c.add(s3);
//通过集合对象的方法获得迭代器对象
Iterator<Student> i = c.iterator();
//遍历集合
while(i.hasNext()) {
Student s = i.next();
System.out.println(s.getName() ", " s.getAge());
}
}
}
(三)List集合
1.List集合概述和特点
- 有序集合(也称为序列),用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素
- 与Set集合不同,列表通常允许重复的元素
List集合特点
- 有序:存储和取出的元素顺序一致
- 可重复:存储的元素可以重复
代码演示:
代码语言:javascript复制public class ListDemo {
public static void main(String[] args) {
//创建List集合对象
List<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
list.add("java");
//获取迭代器(因为List集合继承自Collection集合,所以Collection集合有的方法,List集合也有)
Iterator<String> it = list.iterator();
//用迭代器的方式遍历List集合
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
}
}
2.List集合特有方法
注:以上方法时List集合特有的方法,Collection集合没有这些方法,但是ArrayLIst集合有这些方法,因为ArrayList继承自List集合。
- List集合不仅可以通过迭代器的方式进行遍历集合,也可以用for循环的方式遍历
代码实现:
代码语言:javascript复制import java.util.ArrayList;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
//创建List集合对象
List<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
list.add("java");
//for循环遍历集合
for (int i = 0; i < list.size(); i ) {
String s = list.get(i);
System.out.println(s);
}
}
}
3.案例(List集合存储学生对象并遍历)
创建学生类(省略,具体参考Collection案例)
创建测试类(ListDemo):
代码语言:javascript复制import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
//创建List对象
List<Student> list = new ArrayList<>();
//创建三个学生对象
Student s1 = new Student("学生1", 20);
Student s2 = new Student("学生2", 21);
Student s3 = new Student("学生3", 22);
//将学生对象放入List集合中存储
list.add(s1);
list.add(s2);
list.add(s3);
//遍历List集合(两种方式:for循环和迭代器)
//for循环遍历
for (int i = 0; i < list.size(); i ) {
Student s = list.get(i);
System.out.println(s.getName() ", " s.getAge());
}
//迭代器遍历
Iterator<Student> it = list.iterator();
while(it.hasNext()){
Student s = it.next();
System.out.println(s.getName() ", " s.getAge());
}
}
}
4.并发修改异常
- ConcurrentModificationException
产生原因
- 迭代器遍历的过程中,通过集合对象修改了集合中元素的长度,造成了迭代器获取元素中判断预期修改值和实际修改值不一致
解决方案
- 用for循环遍历,然后用集合对象做对应的操作即可
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("hello");
list.add("java");
list.add("world");
/*
//迭代器
Iterator<String> it = list.iterator();
while(it.hasNext()){
String s = it.next();
if(s.equals("java")){
list.add("javaee");//ConcurrentModificationException(并发修改异常)
}
}
*/
//用for循环解决并发修改异常
for (int i = 0; i < list.size(); i ) {
String s = list.get(i);
if(s.equals("java")){
list.add("javaee");
}
}
System.out.println(list);//[hello, java, world, javaee]
}
}
/*add方法源码
public boolean add(E e) {
modCount ; 实际修改集合的次数 与 预期修改集合的次数不符(exceptedModeCount)
add(e, elementData, size);
return true;
}
*/
//使用get方法内部就不会有上述两个变量(modCount和exceptedModeCount)的比较
5.ListIterator列表迭代器
- 通过List集合的listlterator()方法得到,所以说它是List集合特有的迭代器
- 用于允许程序员沿任一方向遍历列表的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置
ListIterator中的常用方法
- E next():返回迭代中的下一个元素
- boolean hasNext():如果迭代具有更多元素,则返回true
- E previous():返回列表中的上一个元素
- boolean hasPrevious():如果此列表迭代器在相反方向遍历列表时具有更多元素,则返回true
- void add(E e):将指定的元素插入列表
代码演示:
代码语言:javascript复制import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListIteratorDemo {
public static void main(String[] args) {
//创建List集合
List<String> list = new ArrayList<>();
list.add("hello");
list.add("java");
list.add("world");
//创建List迭代器
ListIterator<String> lit = list.listIterator();
while(lit.hasNext()){
String s = lit.next();
if(s.equals("java")){
lit.add("javaee");//此时不会出现并发修改异常,因为底层代码将实际修改集合的次数赋值给了预期修改集合的次数(exceptedModeCount = modCount)
}
}
}
}
6.增强for循环
- 实现Iterator接口的类允许其对象成为增强型for语句的目标
- 它是JDK5之后出现的,其内部原理是一个Iterator迭代器
增强for格式:
格式:
for(元素数据类型 变量名:数组或者Collection集合){
//在此处使用变量即可,该变量就是元素
}
范例:
代码语言:javascript复制int[] arr = {1,2,3,4,5};
for(int i : arr) {
System.out.println(i)
}
7.案例(List集合存储学生对象用三种方式遍历)
创建学生对象(省略,具体参考前面):
创建测试类:
代码语言:javascript复制import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class forDemo {
public static void main(String[] args) {
//创建List集合对象
List<Student> list = new ArrayList<>();
//创建三个学生对象
Student s1 = new Student("学生1", 20);
Student s2 = new Student("学生2", 21);
Student s3 = new Student("学生3", 22);
//将学生对象存入集合中
list.add(s1);
list.add(s2);
list.add(s3);
//普通for循环遍历List集合
for (int i = 0; i < list.size(); i ) {
Student s = list.get(i);
System.out.println(s.getName() ", " s.getAge());
}
//list迭代器遍历List集合
ListIterator<Student> lit = list.listIterator();
while (lit.hasNext()) {
Student s = lit.next();
System.out.println(s.getName() ", " s.getAge());
}
//增强for循环遍历
for(Student i : list){
System.out.println(i.getName() ", " i.getAge());
}
}
}
8.List 集合子类特点
List 集合常用子类:ArrayList,LinkedList
- ArrayList:底层数据结构是数组,查询快,增删慢
- LinkedList:底层数据结构式链表。查询慢,增删快
9.案例(分别使用ArrayList和LinkedList完成存储字符串并遍历)
代码实现:
代码语言:javascript复制import java.util.ArrayList;
import java.util.LinkedList;
import java.util.ListIterator;
public class ArrayListDemo {
public static void main(String[] args) {
//1.ArrayList集合遍历
ArrayList<String> array = new ArrayList<>();
array.add("hello");
array.add("world");
array.add("java");
//普通for循环遍历
for (int i = 0; i < array.size(); i ) {
String s = array.get(i);
System.out.println(s);
}
//迭代器遍历
ListIterator<String> lit = array.listIterator();
while (lit.hasNext()) {
String s2 = lit.next();
System.out.println(s2);
}
//增强for循环遍历
for (String s3 : array) {
System.out.println(s3);
}
//2.LinkedList集合遍历
LinkedList<String> link = new LinkedList<>();
link.add("hello");
link.add("world");
link.add("java");
//普通for循环
for (int i = 0; i < link.size(); i ) {
String s = link.get(i);
System.out.println(s);
}
//迭代器
ListIterator<String> lit2 = link.listIterator();
while (lit2.hasNext()) {
String s2 = lit2.next();
System.out.println(s2);
}
//增强for循环遍历
for (String s3 : link) {
System.out.println(s3);
}
}
}
10.LinkedList集合的特有功能
(四)Set集合
1.Set集合概述和特点
Set集合特点
- 不包含重复元素的集合
- 没有带索引的方法,所以不能使用普通for循环
Set集合练习
- 存储字符串并遍历
import java.util.HashSet;
import java.util.Set;
public class SetDemo {
public static void main(String[] args) {
//创建集合对象
Set<String> set = new HashSet<>();//HashSet对集合的迭代顺序不作任何保证
//添加元素
set.add("hello");
set.add("java");
set.add("world");
//不包含重复元素
set.add("world");//结果只有一个world
//遍历集合
for (String s : set) {
System.out.println(s);
}
}
}
2.哈希值
哈希值:是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
Object类中有一个方法可以获取对象的哈希值
- public int hashCode():返回对象的哈希码值
对象的哈希值特点
- 同一个对象多次调用hashCode()方法返回的哈希值是相同的
- 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同
3.HashSet集合概述和特点
HashSet集合特点
- 底层数据结构是哈希表
- 对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
- 没有带索引的方法,所以不能使用普通for循环遍历
- 由于是Set集合,所以是不包含重复元素的集合
HashSet集合练习
- 存储字符串并遍历
import java.util.HashSet;
import java.util.Iterator;
public class HashSetDemo {
public static void main(String[] args) {
HashSet<String> sh = new HashSet<>();
sh.add("hello");
sh.add("world");
sh.add("java");
//迭代器遍历
Iterator<String> it = sh.iterator();
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
//增强for遍历
for(String s : sh){
System.out.println(s);
}
}
}
4.HashSet集合保证元素唯一性源码分析
HashSet集合添加一个元素过程:
HashSet集合存储元素:
- 要保证元素唯一性,需要重写hashCode()和equals()
5.案例(HashSet集合存储学生对象并遍历)
要求:学生对象的成员变量值相同,我们就认为是同一个对象
代码实现:
创建学生类(需要重写hashCode()和equals()方法来保证元素的唯一性)
代码语言:javascript复制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;
}
//重写重写hashCode()和equals()方法来保证元素的唯一性
@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);
}
}
创建测试类
代码语言:javascript复制import java.util.HashSet;
import java.util.Iterator;
public class HashSetDemo {
public static void main(String[] args) {
HashSet<Student> sh = new HashSet<>();
Student s1 = new Student("学生1", 20);
Student s2 = new Student("学生2", 21);
Student s3 = new Student("学生3", 22);
Student s4 = new Student("学生1",20);//与s1相同
sh.add(s1);
sh.add(s2);
sh.add(s3);
sh.add(s4);//结果并未显示s4,因为与s1位同一个元素,在学生类定义中重写了hashCode()和equals()方法确保了元素的唯一性
//迭代器遍历集合
Iterator<Student> it = sh.iterator();
while (it.hasNext()) {
Student s = it.next();
System.out.println(s.getName() ", " s.getAge());
}
//增强for遍历集合
for(Student s : sh) {
System.out.println(s.getName() ", " s.getAge());
}
}
}
6.LinkedHashSet集合概述和特点
LinkedHashSet集合特点
- 哈希表和链表实现的Set接口,具有可预测的迭代次序
- 由链表保证元素有序,也就是 说元素的存储和取出顺序是一致的
- 由哈希表保证元素唯一,也就是说没有重复的元素
LinkedHashSet集合练习
- 存储字符串并遍历
import java.util.LinkedHashSet;
public class LinkedHashSetDemo {
public static void main(String[] args) {
//LinkedHashSet集合保证了元素的唯一性也保证了存储和取出的顺序的一致性
LinkedHashSet<String> lh = new LinkedHashSet<>();
lh.add("hello");
lh.add("java");
lh.add("world");
lh.add("hello");//元素唯一性,所以结果不显示多余的hello字符串
for (String s : lh) {
System.out.println(s);
}
}
}
7.TreeSet集合概述和特点
TreeSet集合特点
- 元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法 TreeSet():根据其元素的自然排序进行排序 TreeSet(Comparetor comparator):根据指定的比较器进行排序
- 没有带索引的方法,所以不能使用普通for循环遍历
- 由于是Set集合,所以不包含重复元素
TreeSet集合练习
- 存储整数并遍历
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Integer> ts = new TreeSet<>();
//添加元素
ts.add(2);
ts.add(3);
ts.add(1);
//因为它是Set集合,所以不包含重复元素
ts.add(2);
for(Integer it: ts) {
System.out.print(it);//结果为 1 2 3
}
}
}
8.自然排序Comparable的使用
- 用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
- 自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法
- 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
练习:
- 存储学生对象并遍历,创建TreeSet集合使用无参构造方法
- 要求:按照年龄从小到大牌,年龄相同时,按照姓名的字母顺序排序
代码实现:
定义学生类:
代码语言:javascript复制public class Student implements Comparable<Student> {
private String name;
private int age;
public Student() {
}
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 Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Student s) {
// return -1;//降序
// return 0;//元素重复
// return 1;//升序
int flag = this.age - s.age; //this在前为升序,在后为降序
int flag2 = flag == 0 ? this.name.compareTo(s.name) : flag; //String类自带compareTo方法
return flag2;
}
}
创建测试类:
代码语言:javascript复制import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<>();
Student s1 = new Student("学生1",22);
Student s2 = new Student("学生2",23);
Student s3 = new Student("学生3",33);
Student s4 = new Student("学生4",33);
Student s5 = new Student("学生4",33);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);//s5与s4元素重复所以结果不显示
for(Student s:ts) {
System.out.println(s.getName() ", " s.getAge());
}
}
}
9.比较器排序Comparator的使用
- 用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的
- 比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法
- 重写方法时,一定要注意排序规则必须按照要求的主要和次要条件来写
练习:
- 存储学生对象并遍历,创建TreeSet集合使用带参构造方法
- 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
代码实现:
定义一个标准的学生类:(此处省略)
定义测试类:
代码语言:javascript复制import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int flag = s1.getAge() - s2.getAge();
int flag2 = flag == 0 ? s1.getName().compareTo(s2.getName()) : flag;
return flag2;
}
});
Student s1 = new Student("学生1",22);
Student s2 = new Student("学生2",23);
Student s3 = new Student("学生3",33);
Student s4 = new Student("学生4",33);
Student s5 = new Student("学生4",33);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);//s5与s4元素重复所以结果不显示
for(Student s:ts) {
System.out.println(s.getName() ", " s.getAge());
}
}
}
分析:
这里o1表示位于前面的对象,o2表示后面的对象
- 返回-1(或负数),表示不需要交换01和02的位置,o1排在o2前面,asc
- 返回1(或正数),表示需要交换01和02的位置,o1排在o2后面,desc
下面来用我们之前的结论解释为什么 return o2.a - o1.a 就是降序了:
首先o2是第二个元素,o1是第一个元素。无非就以下这些情况: ①: o2.a > o1.a: 那么此时返回正数,表示需要调整o1,o2的顺序,也就是需要把o2放到o1前面,这不就是降序了么。
②:o2.a < o1.a : 那么此时返回负数,表示不需要调整,也就是此时o1 比 o2大, 不还是降序么。
10.案例(不重复的随机数)
编写一个程序,获取10个1~20之间的随机数,要求随机数不能重复,并在控制台输出
代码语言:javascript复制import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
public class SetDemo {
public static void main(String[] args) {
//创建集合对象
//Set<Integer> set = new HashSet<>();//HashSet集合是无序且元素唯一
Set<Integer> set = new TreeSet<>();//TreeSet集合是有序且元素唯一
//创建随机数对象
Random r = new Random();
//判断集合的长度是否小于10
while (set.size() < 10) {
int sum = r.nextInt(20) 1;
set.add(sum);
}
for(Integer i :set) {
System.out.println(i);
}
}
}
(五)Map集合
1.Map集合概述和使用
Map集合概述
- interface Map<K,V> K:键的类型; V:值的类型
- 将键映射到值的对象;不能包含重复的键;每个键可以映射到最多一个值
- 举例:学生的学号和姓名
创建Map集合的对象
- 多态的方式
- 具体的实现类HashMap
代码演示:
代码语言:javascript复制import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args) {
//创建集合对象
Map<String, String> map = new HashMap<>();
//V put (K key,V value) 将指定的值与该映射中的指定键相关联
map.put("19103205", "学生1");
map.put("19103206", "学生2");
map.put("19103204", "学生3");
map.put("19103204", "学生4");//第二次使用put方法相当于修改
//输出集合对象
System.out.println(map);//{19103206=学生2, 19103204=学生4, 19103205=学生1}
}
}
2.Map集合的基本功能
3.Map集合的获取功能
代码演示:
代码语言:javascript复制import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo {
public static void main(String[] args) {
//创建集合对象
Map<String, String> map = new HashMap<>();
//V put (K key,V value) 将指定的值与该映射中的指定键相关联
map.put("19103205", "学生1");
map.put("19103206", "学生2");
map.put("19103204", "学生3");
// V get(Object key):根据键获取值
System.out.println(map.get("19103205"));//学生1
System.out.println(map.get("191032"));//null
//Set<K> keySet():获取所有键的集合
Set<String> set = map.keySet();
for(String i : set){
System.out.println(i);
}
//Collection<V> values():获取所有值的集合
Collection<String> collection = map.values();
for(String i :collection) {
System.out.println(i);
}
}
}
4.Map集合的遍历
(1)方式一
遍历思路:
- 获取所有键的集合。用keySet()方法实现
- 遍历键的集合,获取到每一个键。用增强for实现
- 根据键去找值。用get(Object key)方法实现
代码演示:
代码语言:javascript复制import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo {
public static void main(String[] args) {
//创建集合对象
Map<String, String> map = new HashMap<>();
//添加
map.put("19103205", "学生1");
map.put("19103206", "学生2");
map.put("19103204", "学生3");
//遍历
Set<String> keySet = map.keySet();
//遍历键的集合,获取到每一个键
for (String key : keySet) {
//根据键去找值
String value = map.get(key);
System.out.println(key "," value);
}
}
}
(2)方式二
遍历思路:
- 获取所有键值对对象的集合 Set<Map.Entry<K,V>> entrySet():获取所有键值对对象的集合
- 遍历键值对对象的集合,得到每一个键值对对象 用增强for实现,得到每一个Map.Entry
- 根据键值对对象获取键和值 用getKey()得到键 用getValue()得到值
代码演示:
代码语言:javascript复制import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo {
public static void main(String[] args) {
//创建集合对象
Map<String, String> map = new HashMap<>();
//添加
map.put("19103205", "学生1");
map.put("19103206", "学生2");
map.put("19103204", "学生3");
//遍历
Set<Map.Entry<String, String>> entrySet = map.entrySet();
for (Map.Entry<String, String> me : entrySet) {
String key = me.getKey();
String value = me.getValue();
System.out.println(key "," value);
}
}
}
5.案例(HashMap嵌套ArrayList)
代码语言:javascript复制import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
public class HashMapDemo2 {
public static void main(String[] args) {
//创建HashMap集合
HashMap<String, ArrayList<String>> hm = new HashMap<>();
//创建ArrayList集合,并添加元素
ArrayList<String> sgyy = new ArrayList<>();
sgyy.add("诸葛亮");
sgyy.add("赵云");
//将ArrayList作为元素添加到集合中
hm.put("三国演义", sgyy);
ArrayList<String> xyj = new ArrayList<>();
xyj.add("唐僧");
xyj.add("孙悟空");
hm.put("西游记", xyj);
ArrayList<String> shz = new ArrayList<>();
shz.add("武松");
shz.add("鲁智深");
hm.put("水浒传", shz);
//遍历
Set<String> keySet = hm.keySet();
for (String key : keySet) {
System.out.println(key);
ArrayList<String> value = hm.get(key);
for (String array : value) {
System.out.print(array ", ");
}
System.out.println();
}
}
}
6.统计字符串中每个字符出现的次数
代码实现:
代码语言:javascript复制import java.util.HashMap;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;
public class HashMapDemo3 {
public static void main(String[] args) {
//创建HashMap集合(无顺序)
//HashMap<Character, Integer> hm = new HashMap<>();
//创建TreeMap集合(可以有顺序)
TreeMap<Character, Integer> hm = new TreeMap<>();
//键盘录入
Scanner sc = new Scanner(System.in);
System.out.println("请输入一组字符串:");
String s = sc.nextLine();
//遍历字符串
for (int i = 0; i < s.length(); i ) {
//获取到每一个字符
char key = s.charAt(i);
//将字符作为键值到HashMap中进行比较,看返回结果
Integer value = hm.get(key);
if (value == null) {//如果返回结果为空,则表示这是第一个存储进去的元素
hm.put(key, 1);
} else { //如果结果不为空,则说明集合中存在这个键及元素,所以数量(value)加1
value ;
hm.put(key, value);//将新的键和值重新添加
}
}
//遍历HashMap集合,得到键和值,按要求进行拼接
StringBuilder sb = new StringBuilder();
Set<Character> keySet = hm.keySet();
for (Character key : keySet) {
Integer value = hm.get(key);
sb.append(key).append("(").append(value).append(")");
}
//将StringBuilder类型转为String类型
String result = sb.toString();
//输出结果
System.out.print(result);
}
}
(六)Collections工具类
1.Collections概述和使用
Collections类的概述
- 是针对集合操作的工具类
Collections类的常用方法
代码演示:
代码语言:javascript复制import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CollectionsDemo {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(20);
list.add(10);
list.add(40);
list.add(50);
list.add(30);
//将指定的序列按升序排列
Collections.sort(list);
//将指定的序列反转
Collections.reverse(list);
//使用默认的随机源随机排列指定的元素
Collections.shuffle(list);
System.out.println(list);
}
}