目录
一、集合类体系结构
二、Collection概述和使用
1.Collection的常用方法
2.Collection集合的遍历
(1)迭代器遍历法
- Iterator:迭代器,集合的专用遍历方式
- Iterator<E> iterator():返回集合中的迭代器对象,该迭代器对象默认指向当前集合的0索引。
- Iterator中的常用方法
- boolean hasNext():判断当前位置是否有元素可以被取出
- E next():获取当前位置的元素将迭代器对象移向下一个索引位置
public class test_04 {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
collection.add("a");
collection.add("b");
collection.add("c");
collection.add("v");
//1.获取迭代器的对象
//迭代器对象一旦被创建出来,默认指向集合的0索引位置
Iterator<String> it = collection.iterator();
//2.利用迭代器的方法进行遍历
System.out.println(it.hasNext());//当前位置是否有元素可以被取出
System.out.println(it.next());//取出当前位置的元素+将迭代器往后移动一个索引的位置
while(it.hasNext()){
System.out.println(it.next());
}
}
}
(2)增强for进行遍历法
- 增强for:简化数组和Collection集合的遍历,其内部原理是一个Iterator迭代器 实现Iterable接口的类才可以使用迭代器和增强for
- 增强for的格式:for(元素数据类型 变量名 : 数组或者Collection集合) {//在此处使用变量即可,该变量就是元素 }
- 范例:ArrayList<String> list = new ArrayList<>(); //添加一些元素 for(String s : list) { System.out.println(i); }
练习:创建一个集合,有元素 a b b c d 使用循环遍历这个集合,判断当前获取到的元素是 否为b,如果是就删除。(使用三种遍历方式)
import java.util.ArrayList;
import java.util.Iterator;
public class test_05 {
public static void main(String[] args) {
method1();//普通的删除方法,当集合中有两个元素挨着的时候就不可以进行删除所有的元素,只会删除其中的一个
method2();//使用迭代器的方法进行遍历
method3();//使用增强for的方式进行遍历
}
public static void method1() {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("d");
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
//list中获取一个元素,用的是get
if("b".equals(s)){
list.remove(i);
i--;//当加上一个i--的回头操作就可以删除所有想要删除的元素。
}
}
System.out.println(list);
}
public static void method2() {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("d");
Iterator<String> it = list.iterator();
while (it.hasNext()){
String s = it.next();
if("b".equals(s)){
it.remove();
}
}
System.out.println(list);
}
public static void method3() {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("d");
for (String s : list) {
if("b".equals(s)){
list.remove(s);
}
}
System.out.println(list);
}
}
三种循环的使用场景
- 如果需要操作索引,使用普通for循环
- 如果在遍历的过程中需要删除元素,请使用迭代器
- 如果仅仅想遍历,那么使用增强for
三、List集合的概述和使用
1. List集合的概述和特点
List集合的概述:
- 有序集合,这里的有序指的是存取顺序
- 用户可以精确控制列表中每个元素的插入位置。
- 用户可以通过整数索引访问元素,并搜索列表中的元素 与Set集合不同,列表通常允许重复的元素
List集合的特点:
- 有序:存储和取出的元素顺序一致
- 有索引:可以通过索引操作元素
- 可重复:存储的元素可以重复
2.List集合特有的方法
3.List常用集合实现类ArrayList和LinkedList
- ArrayList:底层数据结果是数组,查询快,删减慢;
- LinkedList:底层数据结构是链表,查询慢,增删快
LinkedList集合特有的功能:
四、Set集合的概述和使用
1.Set集合特点
- 可以去除重复
- 存取顺序不一致
- 没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取,删除Set集合里面的元素
2.Set常用集合实现类TreeSet和HashSet
(1)TreeSet集合特点
- 不包含重复元素的集合
- 没有带索引的方法
- 可以将元素按照规则进行排序(想要用TreeSet必须指定排序规则)
(2)TreeSet中的排序方式
第一种方式:自然排序Comparable的使用
- 使用空参构造创建TreeSet集合
- 自定义的Student类实现Comparable接口
- 重写里面的compareTo方法
自然排序简单原理
- 如果返回值为负数,表示当前存入的元素是较小值,存左边
- 如果返回值为0,表示当前存入的元素跟集合中元素重复了,不存
- 如果返回值为正数,表示当前存入的元素是较大值,存右边
用TreeSet的第一种排序方式实现下列需求:
- 按照年龄从小到大排,如果年龄一样,则按照姓名首字母排序
- 如果姓名和年龄一样,才认为是同一个学生对象,不存入。
下面展示的是在Student类中进行重写compareTo方法,具体的前面两步没有展示。
public int compareTo(Student o) {
//按对象的年龄进行排序年龄从小到大排列
//年龄是主要判断条件
int result = this.getAge()-o.getAge();
//当年龄的判断条件一样的时候,才会进行姓名的判断
result=result ==0?this.getName().compareTo(o.getName()):result;
//下面的compareTo和上面的是不一样的,下面的使用字符串在调用compareTo,
//代表的意思是按照字典顺序比较两个字符串,例如下面举个例子来进行说明
//String s1="aaa";
//String s2="ab";
//System.out.println(s1.compareTo(s2));-1
//为什么会是-1,首先比较的是第一个字母,如果第一个字母是一样的,那么就继续比较后面的字母
//当不一样的时候,就拿着对应的码表值97,减去b的码表值98;
//认为a是要比b小
return result;
}
第二种方式:比较器排序Comparator
- TreeSet的带参构造方法使用的是比较器排序对元素进行排序的
- 比较器排序,就是让集合构造方法接收Comparator的实现类对象,
- 重写compare(T o1,T o2)方法 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
用TreeSet的第二种排序方式实现下列需求:
- 按照年龄从小到大排,如果年龄一样,则按照姓名首字母排序
- 如果姓名和年龄一样,才认为是同一个老师对象,不存入。
import java.util.Comparator;
import java.util.TreeSet;
public class test_08 {
public static void main(String[] args) {
//实现TreeSet自然排序的第二种方法,用TreeSet比较器排序
TreeSet<Teacher> ts = new TreeSet<>(new Comparator<Teacher>() {
@Override
public int compare(Teacher o1, Teacher o2) {
//01表示要存入的那个元素
//02表示已经存入到集合中的元素
int result = o1.getAge()-o2.getAge();
result = result==0?o1.getName().compareTo(o2.getName()):result;
return 0;
}
});
Teacher t1 = new Teacher("zhangsan",12);
Teacher t2 = new Teacher("lisi",15);
Teacher t3 = new Teacher("wangwu",18);
ts.add(t1);
ts.add(t3);
ts.add(t2);
System.out.println(ts);
}
}
两种方式比较小结:
- 自然排序:自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序。
- 比较器排序:创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序。
- 在使用的时候,默认使用自然排序,当自然排序不满足现在的需求时,使用比较器排序
【案例】按照字符串长度进行排序
- 请自行选择比较器排序和自然排序两种方式;
- 要求:存入四个字符串, “c”, “abc”, “acd”, “avfwea” 按照长度排序,如果一样长则按照首字母排序。
- 注意:这里就只能采用Comparator比较器进行排序,因为我们不能改变底层java已经对String这些封装好的Comparable接口。
public class test_09 {
public static void main(String[] args) {
//java中的Integer,String这些类java已经提供给我们了,所以第一种就不能满足我们的需求;
//这时候就需要选择第二种Comparator方法;
TreeSet<String> t = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int result = o1.length()-o2.length();
result = result==0?o1.compareTo(o2):result;
return result;
}
});
t.add("a");
t.add("abc");
t.add("acb");
t.add("avfwea");
System.out.println(t);
}
}
(3)HashSet集合特点
- 底层数据结构是哈希表
- 对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
- 没有带索引的方法,所以不能使用普通for循环遍历
- 由于是Set集合,所以元素唯一
哈希值:
- 哈希值:是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
- Object类中有一个方法可以获取对象的哈希值:public int hashCode():返回对象的哈希码值
- 同一个对象多次调用hashCode()方法返回的哈希值是相同的
- 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同
五、Map集合的概述和使用
1.Map集合的特点
- Interface Map<K,V> K:键的数据类型;V:值的数据类型
- 键不能重复,值可以重复
- 键和值是一一对应的,每一个键只能找到自己对应的值 (键 + 值)
- 这个整体 我们称之为“键值对”或者“键值对对象”,在Java中叫做“Entry对象”
2.Map集合的基本功能和获取功能
采用上面的方法进行遍历的方式有三种:
第一种方式:先获取所有的键,然后再根据键去寻找对应的值
第二种方式:先获取所有的键值对对象,然后再获取每一个键和每一个值
第三种方式:采用的是map中的forEach()方式,两个参数对应的是map中的键和值。
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class test_10 {
public static void main(String[] args) {
//创建集合并添加元素
//map的遍历方式一
Map<String,String> map = new HashMap<>();
map.put("1号灰太狼","1号红太狼");
map.put("2号灰太狼","2号红太狼");
map.put("3号灰太狼","3号红太狼");
map.put("4号灰太狼","4号红太狼");
map.put("5号灰太狼","5号红太狼");
map.put("6号灰太狼","6号红太狼");
map.put("7号灰太狼","7号红太狼");
// //第一种遍历方式
// //获取到所有的键,再通过键来找相应的值
Set<String> keys = map.keySet();
//遍历Set集合得到每一个键
for (String key : keys) {
map.get(key);
}
//遍历方式二
//首先要获取到所有的键值对对象,再获取每一个键和每一个值
//Set集合中装的时键值对象
//而Entry里面装的时键和值
Set<Map.Entry<String,String>> entries = map.entrySet();
for (Map.Entry<String, String> entry : entries) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"....."+value);
}
//遍历方式三
//利用map中的forEach()方法
map.forEach(
(String key,String value)->{
System.out.println(key+"......"+value);
}
);
}
}
3.Map常用集合实现类TreeMap和HashMap
(1)TreeMap的特点
- TreeMap底层是红黑树结构的
- 依赖自然排序或者比较器排序,对键进行排序
- 如果键存储的是自定义对象,需要实现Comparable接口或者在创建TreeMap对象时候给出比较器排序规则
(2)HashMap的特点
- HashMap是Map里面的一个实现类。
- 没有额外需要学习的特有方法,直接使用Map里面的方法就可以了
- HashMap跟HashSet一样底层是哈希表结构的