集合
Collection
Collection集合概述:
- 是单列集合的顶层接口,它表示一组对象,这些对象也被称为Collection的元素。
- JDK不提供接口的任何直接实现,它提供具体的子接口(如Set和List)实现。
创建Collection集合的对象:
-
多态的方式,
-
具体的实现类ArrayLis
Collection<String> c = new ArrayList<String>(); // Collection集合常用方法: // boolean add(E e):添加元素 // boolean remove(Object o):从集合中移除指定的元素 // void clear():清除集合中的元素 // boolean contains(Object o):判断集合中是否存在指定的元素 // boolean isEmpty(): 判断集合是否为空 // int size():集合的长度,就是集合中元素的个数 // Interface Iterator<E> 迭代器 // 添加元素 c.add("hello"); c.add("hello"); c.add("world"); c.add("orange"); // 移除元素 System.out.println(c.remove("world")); // 判断是否有orange元素 System.out.println(c.contains("orange")); // 清空元素 c.clear(); // 判断集合是否为空 System.out.println(c.isEmpty()); // 返回集合的长度 System.out.println(c.size()); // 重写了toString方法,输出集合 System.out.println(c);
Collection集合的遍历
* Interface Iterator<E> E - 此迭代器返回的元素的类型
* boolean hasNext()如果迭代具有更多的元素,则返回true 。 (换句话说,如果next()返回一个元素而不是抛出一个异常,则返回true )
* E next()返回迭代中的下一个元素。
```java
// Iterator中的常用方法
// E next(): 返回迭代的中的下一个元素
// boolean hasNext(): 如果迭代具有更多元素,返回true
Iterator<String> it = c.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
List
-
有序集合,也称为序列,用户可以精确控制列表中每个元素的插入位置,用户可以通过整数索引访问元素。
-
与Set集合不同,列表通常允许重复的元素。
特点:
- 有序:存储和取出的顺序是一致的。
- 可重复:存储的元素是可以重复的。
在java.util包下的一个接口----Interface List |
---|
继承Collection--------public interface Listextends Collection |
List常用的方法:
E get(int index)// 返回此列表中指定位置的元素。
参数: index
- 要返回的元素的索引
结果:该列表中指定位置的元素
E set(int index,E element)// 用指定的元素(可选操作)替换此列表中指定位置的元素。
void add(int index,E element)// 将指定的元素插入此列表中的指定位置(可选操作)。 将当前位于该位置的元素(如果有)和任何后续元素(向其索引添加一个)移动。
boolean add(E e)// 将指定的元素追加到此列表的末尾(可选操作)。
boolean remove(Object o)
// 从列表中删除指定元素的第一个出现(如果存在)(可选操作)。 如果此列表不包含该元素,则它将保持不变。 更正式地,删除具有最低索引`i`的元素,使得`(o==null ? get(i)==null : o.equals(get(i)))` (如果这样的元素存在)。 如果此列表包含指定的元素(或等效地,如果此列表作为调用的结果而更改),则返回`true` 。
并发修改异常
Iterator
// 创建List集合对象
List<String> l = new ArrayList<String>();
// 添加对象
l.add("hello");
l.add("world");
l.add("hello");
// 并发处理异常
Iterator<String> it = l.iterator();
while (it.hasNext()) {
String s = it.next();
if (s.equals("world")) {
l.add("javase");
}
}
// ConcurrentModificationException
// 正确的做法
for (int i = 0; i < l.size(); i++) {
String s = l.get(i);
if (s.equals("world")) {
l.add("javase");
}
}
列表迭代器
ListIterator: 列表迭代器
- 通过List集合的IistIterator()方法获得的,所以说是List集合特有的迭代器。
- 用于允许沿任一方向遍历列表的列表迭代器,可以在迭代期间修改列表,并获取列表中迭代器的当前位置。
listIterator 的常用方法
- E next() :返回迭代器中的下一个元素
- boolean hasNext() : 如果迭代器有更多的元素,就返回true
- E previous() : 返回列表中上一个元素
- boolean hasPrevious() : 如果此列表迭代器在相反方向遍历列表时有更多的元素,就返回true
- void add(E e) : 将指定的元素插入列表
增强for循环
增强for循环:简化数组和Collection集合的遍历
- 实现Iterable接口的类允许其对象成为增强型for语句的目标
- 它是JDK5之后出现的,其内部原理是Iterator迭代器
其格式:
for(元素数据类型 变量名 : 数组或Collection集合) {
//此处使用变量即可,该变量就是元素
}
int[] arr = {1,2,34,4};
for (int a : arr) {
System.out.println(a);
}
String[] s = {"ss","aa","dd"};
for (String a : s) {
System.out.println(a);
}
List<String> list = new ArrayList<String>();
list.add("hello");
list.add("java");
list.add("world");
for (String a : list) {
System.out.println(a);
}
栈
栈:先进后出
队列
队列:先进先出
从后端进,入队列
从前端出,出队列
数组
查询快,增删慢的模型
链表
增删块,查询慢的模型
List集合子类特点
List集合的常见子类:ArrayList和LinkedList
- ArrayList底层数据是数组,查询快,增删慢
- LinkedList底层数据是链表,查询慢,增删快
LinkedList集合的特有功能
void addFirst(E e)
在该列表开头插入指定的元素。
void addLast(E e)
将指定的元素追加到此列表的末尾。
E getFirst()
返回此列表中的第一个元素。
E getLast()
返回此列表中的最后一个元素。
E removeFirst()
从此列表中删除并返回第一个元素。
boolean removeFirstOccurrence(Object o)
删除此列表中指定元素的第一个出现(从头到尾遍历列表时)。
E removeLast()
从此列表中删除并返回最后一个元素。
LinkedList<String> lin = new LinkedList<String>();
lin.add("董卿");
lin.add("陈数");
lin.add("苏瑾");
for (String a : lin) {
System.out.println(a);
}
lin.addFirst("刘敏涛");
lin.removeLast();
System.out.println(lin.getFirst());
System.out.println(lin);
//输出结果
//董卿
//陈数
//苏瑾
//刘敏涛
//[刘敏涛, 董卿, 陈数]
Set
不重复
public interface Setextends Collection
哈希值
- 哈希值JDK根据对象的地址值或者字符串或者数字转化成int类型的数值。
Object类有一个方法可以获取对象的哈希值
- public int hashCode() : 返回对象的哈希值
对象的哈希值的特点:
-
同一个对象多次调用hasCode()方法返回的哈希值是相同的
-
默认情况下,不同对象的哈希值是不同的,但重写hasCode()方法,可以让哈希值相同
hashSet集合
-
hasSet集合底层数据是哈希表
-
对集合的迭代顺序不做任何的保证,也就是说不保证存储和取出的顺序一致
-
没有带索引的方法啊,所以不能使用普通的for循环遍历
-
由于是Set集合,所以不包含重复的元素
import java.util.HashSet;
HashSet<String> s = new HashSet<String>();
s.add("hello");
s.add("world");
s.add("java");
s.add("world");
for(String a : s) {
System.out.println(a);
}
// 输出结果
// world
// java
// hello
LinkedHashSet集合
其特点:
-
哈希表和链表实现的Set接口,具有可预测的迭代次序
-
由链表保证元素有序,也就是说保证存储和取出的顺序一致
-
由哈希表保证元素唯一,也就是说没有重复的元素
LinkedHashSet<String> link = new LinkedHashSet<String>();
link.add("hello");
link.add("world");
link.add("java");
link.add("hello");
for (String a : link) {
System.out.println(a);
}
//输出结果
//hello
//world
//java
TreeSet集合
TreeSet集合有序,是指按照一定的规则进行排序,具体排序方法取决于构造方法
TreeSet() :根据元素的自然排序进行排序
TreeSet(Comparator comparator) : 根据指定的比较器进行排序
没有索引的方法,不能使用for循环遍历
由于是Set集合,不包含重复的元素
自然排序Comparable的使用
-
用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
-
自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法
-
重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
// 重写compareTo方法
public int compareTo(Student s) {
int num = this.age - s.age;
int num2 = num == 0 ? this.name.compareTo(s.name) : num;
return num2;
}
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;
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;
}
@Override
public int compareTo(Student s) {
int num = this.age - s.age;
int num2 = num == 0 ? this.name.compareTo(s.name) : num;
return num2;
}
}
public class Link02 {
public static void main(String[] args) {
TreeSet<Student> s = new TreeSet<Student>();
Student s1 = new Student("小张",13);
Student s2 = new Student("小林",23);
Student s3 = new Student("小李",19);
Student s4 = new Student("小孙",23);
s.add(s1);
s.add(s2);
s.add(s3);
s.add(s4);
for (Student a : s) {
System.out.println(a.getName() + "," + a.getAge());
}
}
// 输出结果
小张,13
小林,19
小李,23
小孙,23
比较器排序Comparator的使用
-
用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的
-
比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法
-
重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
public class Tree03 {
public static void main(String[] args) {
TreeSet<Student> s = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int num = s1.getAge() - s2.getAge();
int num2 = num == 0? s1.getName().compareTo(s2.getName()) : num;
return num2;
}
});
Student s1 = new Student("小张",13);
Student s2 = new Student("小林",23);
Student s3 = new Student("小李",19);
Student s4 = new Student("小孙",23);
s.add(s1);
s.add(s2);
s.add(s3);
s.add(s4);
for (Student a : s) {
System.out.println(a.getName() + "," + a.getAge());
}
}
}
// 输出结果
小张,13
小林,19
小李,23
小孙,23