Collection - List - Set
1 Collection
1.1 含义
Collection 代表单列集合,每个元素 (数据) 只包含一个值, 等一会提到另一种集合Map代表双列集合, 即每个元素包含两个值 (键值对) Map有点类似于Pyhton的dict(字典), dict为无序排列的双列集合
1.2 体系
1.2.1 List系列集合
添加的元素是有序、可重复、有索引.
主要有以下两类: ArrayList, LinkedList
1.2.2 Set系列集合
添加的元素是无序、不重复、无索引。
主要有以下两类: HashSet (LinkedHashSet) , TreeSet
1.3 优点
Collection是单列集合的祖宗,它规定的方法 (功能) 是全部单列集合都会继承的
1.4 常用方法
- 把给定的对象添加到当前集合中 : public boolean add(E e)
- 清空集合中所有的元素: public void clear()
- 把给定的对象在当前集合中删除: public boolean remove(E e)
- 判断当前集合中是否包含给定的对象: public boolean contains(Object obj)
- 判断当前集合是否为空: public boolean isEmpty()
- 返回集合中元素的个数: public int size()
- 把集合中的元素,存储到数组中: public Object[] toArray()
1.5 遍历方式
1.5.1 使用迭代器
1) 先获取迭代器对象: Iterator it = col.iterator();
2) 再使用循环遍历: Ps:迭代器要是遍历完了,就没有办法再遍历了, 只能重新获取一个迭代器
while (it.hasNext()){ //先判断有没有数据
System.out.println(it.next());
}
1.5.2 增强for循环
for (元素的数据类型 变量名 : 数组或者集合) {
}
int[] arr = {213,124,1132,214,123,111,223,4535,23};
for(int i : arr){
System.out.println(i);
}
1.5.3 forEach(lambda)
//构建匿名内部类重写方法
lists.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
//lampda方法
lists.forEach(s -> {
System.out.println(s);
});
//调用方法
list.forEach(System.out::println);
2 List
2.1 特点
List 是一个有序集合,可以保存重复的元素。它的主要特点有: 有序, 可重复, 有索引
2.2 分类
2.2.1 ArrayList
ArrayList的底层是数组, 特点是查询快, 增删慢.
适用于大量数据的查询, 不频繁的增删
2.2.2 LinkedList
LinkedList的底层是双链表. 特点是查询慢, 增删相对较快, 但对首尾元素进行增删改查的速度也非常快. LinkedList的应用方式有两种, 队列和栈, 前者遵循先进先出的规则, 后者遵循先进后出的规则, 和JVM的栈内存类似.
特有方法:
- 在该列表开头插入指定的元素: public void addFirst(E e)
- 将指定的元素追加到此列表的末尾: public void addLast(E e)
- 返回此列表中的第一个元素: public E getFirst()
- 返回此列表中的最后一个元素: public E getLast()
- 从此列表中删除并返回第一个元素: public E removeFirst()
- 从此列表中删除并返回最后一个元素: public E removeLast()
2.3 常有方法
- 在此集合中的指定位置插入指定的元素: void add(int index,E element)
- 删除指定索引处的元素,返回被删除的元素: E remove(int index)
- 修改指定索引处的元素,返回被修改的元素: E set(int index,E element)
- 返回指定索引处的元素: E get(int index)
import java.util.LinkedList;
public class test {
public static void main(String[] args) {
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("Yui");
System.out.println(linkedList);
// addFirst
linkedList.addFirst("Hi-chan");
System.out.println(linkedList);
// addlast
linkedList.addLast("Yukirin");
System.out.println(linkedList);
// getfirst
System.out.println(linkedList.getFirst());
// getlast
System.out.println(linkedList.getLast());
// remove first/last
linkedList.removeFirst();
linkedList.removeLast();
System.out.println(linkedList);
// replace
linkedList.set(0,"Yuiyui");
System.out.println(linkedList);
}
}
2.4 遍历方法
1) for循环(因为List集合有索引)
2) 迭代器
3) 增强for循环
4) Lambda表达式
3 红黑树
红黑树是一种增删改查数据性能相对都较好的结构.
是一种能够自动调节的平衡二叉树, 保证树高度为最小(每个枝干红/黑元素相等), 使其能更高效查找数据
4 Set
4.1 特点
Set 是一个不允许重复元素的无序集合。其特点是: 无序、不重复、无索引
4.2 分类
4.2.1 HashSet
特点是: 无序、不重复、无索引. 插入和查询操作效率较高,但是不能保证元素的顺序。
底层: JDK8开始,哈希表 = 数组+链表+红黑树
4.2.2 LinkedHashSet
特点是: 有序、不重复、无索引
底层: 依然是基于哈希表(数组+链表+红黑树)实现的. 但是, 它的每个元素都额外的多了一个双链表的机制记录它前后元素的位置, 所以可以有序排列, 保证元素的插入顺序 . 插入和查询操作效率较高
4.2.3 TreeSet
特点是: 不重复、无索引、可排序(默认升序排序 ,按照元素的大小,由小到大排序)
底层: 底层是基于红黑树实现的排序。
排序规则:
1) 对于数值类型:Integer, Double, 默认按照数值本身的大小进行升序排序。
2) 对于字符串类型:默认按照首字符的编号升序排序
3) 对于自定义类型如Student对象, TreeSet默认是无法直接排序的;
i. 让自定义的类实现Comparable接口, 重写里面的compareTo方法来指定比较规则;
public class Student implements Comparable<Student>{
//此处省略 参数. 构造器. getset方法等
@Override
public int compareTo(Student o) {
int i = Double.compare(this.age, o.age);
return i;
}
}
ii. 通过调用TreeSet集合有参数构造器, 可以设置Comparator对象 (比较器对象,用于指定比较规则)。
TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int i = Double.compare(o1.getAge(),o2.getAge());
return i;
}
PS: TreeSet 去重的原理是如果用于排序比较的字段
4.3 存储过程
1) 根据hashCode值计算元素存放的位置
2) 如果这个位置没有元素,直接存储
3) 如果这个位置有元素调用equals比较
4) equals()为false,存储
5) equals()为true,不存储(认为是相同的元素)
6) 【总结】:如果想集合存放对象去重,重写hashCode方法和equals方法
import java.util.Objects;
public class Student{
//此处省略 参数. 构造器. getset方法等
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public boolean equals(Object obj) {
// 传进来是同一个对象就==
if(this == obj){
return true;
}
// 空值false, 不是Student类false
if(obj == null||this == null||!(obj instanceof Student)){
return false;
}
Student s = (Student) obj;
// 对象内容一样==
if((this.age==s.age)&&(this.name==s.name)){
return true;
}
return false;
}
}