一、集合接口
集合是Java API所提供的一系列类,可以用于动态存放多个对象 (集合只能存对象)
集合与数组的不同在于,集合是大小可变的序列,而且元素类型可以不受限定,只要是引用类型。(集合中不能放基本数据类型,但可以放基本数据类型的包装类)
集合类全部支持泛型,是一种数据安全的用法。
Collection接口规范了list和set子类的方法规范,即集合的基本使用方法,与Map接口不同的是Collection的子类实现类是存储的单个值,可以获取迭代器进行遍历;Map存储的是Key - value键值对,不可以获取迭代器,不能遍历(Map可以间接遍历)。
List接口的子类主要是有下标的集合实现类,数据存储是有序的;Set的实现类没有下标,是无序的(无序:存入顺序和取出顺序不一致,无序不等于随机),但是 LinkedHashSet 是有序的,因为底层是相似链表结构。
总结:List接口有序且可重复(因为List接口中添加了许多针对下标操作的方法),实现类:ArrayList,LinkedList,Vector;Set接口特点:无序且不可重复,实现类:HashSet,LinkedHashSet,TreeSet,Stack。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sSZ4Od81-1628512183007)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20210809190537428.png)]
二、ArrayList类
1、了解ArrayList
ArrayList list = new ArrayList();
list.add("字符串");
list.add(100);
list.add(123.123);
使用 ArrayList 方法 + 泛型 泛型:数据安全的作法,规定集合应该存储什么样的数据类型
ArrayList<String> list = new ArrayList<>();
list.add("麻生希");
list.add("椎名空");
list.add("爱田奈奈");
list.add("三上悠亚");
list.add("明日花绮罗");
int size = list.size();
System.out.println("获取元素的个数:" + size);
list.set(0, "林成");
String elment = list.get(0);
System.out.println("获取指定下标上的元素:" + elment);
list.add(1, "卢永刚");
ArrayList<String> newList1 = new ArrayList<>();
Collections.addAll(newList1, "aaa","bbb","ccc","明日花绮罗");
list.addAll(newList1);
ArrayList<String> newList2 = new ArrayList<>();
Collections.addAll(newList2, "ddd","eee","fff");
list.addAll(3, newList2);
System.out.println("判断集合中是否包含某个元素:" + list.contains("椎名空"));
ArrayList<String> newList3 = new ArrayList<>();
Collections.addAll(newList3, "eee","ddd","fff","ggg");
System.out.println("判断集合中是否包含某个集合中所有元素:" + list.containsAll(newList3));
int index = list.indexOf("椎名空");
System.out.println("获取元素在集合中的下标:" + index);
boolean empty = list.isEmpty();
System.out.println("判断集合中是否没有元素:" + empty);
list.remove(3);
list.remove("eee");
ArrayList<String> newList4 = new ArrayList<>();
Collections.addAll(newList4, "fff","aaa","bbb","xxx");
list.removeAll(newList4);
ArrayList<String> newList5 = new ArrayList<>();
Collections.addAll(newList5, "林成","卢永刚","椎名空","爱田奈奈","三上悠亚","yyy");
list.retainAll(newList5);
list.set(2, "深田咏美");
List<String> subList = list.subList(1, 3);
Object[] array = subList.toArray();
System.out.println(Arrays.toString(array));
System.out.println("-------------");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("-------------");
for (String element : list) {
System.out.println(element);
}
System.out.println("-------------");
Iterator<String> it = list.iterator();
while(it.hasNext()){
String e = it.next();
System.out.println(e);
}
System.out.println("-------------");
ListIterator<String> listIterator = list.listIterator();
while(listIterator.hasNext()){
String e = listIterator.next();
System.out.println(e);
}
2、泛型在集合中的使用
含义:数据安全的作用
public class A {
}
public class B extends A {
}
public class MyArrayList<E> {
public boolean add(E e){
return true;
}
}
泛型限定:
?表示什么类型都可以
? extends A 表示元素必须是A类或A的子类
? super A 表示元素必须是A类或A的父类
MyArrayList<String> list1 = new MyArrayList<>();
list1.add("abc");
MyArrayList<Integer> list2 = new MyArrayList<>();
list2.add(123);
public ArrayList<?> method01(){
ArrayList<String> list = new ArrayList<>();
return list;
}
public ArrayList<? extends A> method02(){
ArrayList<A> list = new ArrayList<>();
return list;
}
public ArrayList<? super A> method03(){
ArrayList<A> list = new ArrayList<>();
return list;
}
三、LinkedList 类
LinkedList 的用法基本上与 ArrayList 相同,但是多了俩个用法
1、LinkedList 队列模式
特点:先进先出
LinkedList<String> list = new LinkedList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
while(!list.isEmpty()){
String element = list.removeFirst();
System.out.println(element);
}
System.out.println("集合中元素的个数:" + list.size());
2、LinkedList 栈模式
特点:先进后出
LinkedList<String> list = new LinkedList<>();
list.add("林成1");
list.add("林成2");
list.add("林成3");
list.add("林成4");
list.add("林成5");
while(!list.isEmpty()){
String element = list.removeLast();
System.out.println(element);
}
System.out.println("集合中元素的个数:" + list.size());
四、迭代器
含义:遍历集合中的数据
foreach底层原理 : foreach底层由迭代器实现
for (String e : list) {
System.out.println(e);
}
分类:Iterator 和 ListIterator
Iterator 和 ListIterator 区别:
Iterator :Collection接口下所有的实现类都可以获取的迭代器,可以在遍历时删除元素
ArrayList<String> list = new ArrayList<>();
list.add("林成1");
list.add("林成2");
list.add("林成3");
list.add("林成4");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String element = it.next();
if(element.equals("林成2")){
it.remove();
}
}
for (String element : list) {
System.out.println(element);
}
Iterator底层实现有一个操作数记录,如果在遍历时,对集合的操作都会使得操作数增加 1 ,调用it.hasNext()会检查操作数是否变化,如果变化则会抛出异常。
ListIterator :List接口下所有的实现类可以获取的迭代器,可以在遍历时删除、替换、添加元素,也可以指定下标开始遍历,还可以倒叙遍历
ArrayList<String> list = new ArrayList<>();
list.add("林成1");
list.add("林成2");
list.add("林成3");
list.add("林成4");
ListIterator<String> listIterator = list.listIterator();
while(listIterator.hasNext()){
String element = listIterator.next();
if(element.equals("林成2")){
listIterator.set("卢永刚");
}
}
while(listIterator.hasNext()){
String element = listIterator.next();
if(element.equals("林成2")){
listIterator.add("卢永刚");
}
}
for (String element : list) {
System.out.println(element);
}
ListIterator<String> listIterator = list.listIterator(1);
while(listIterator.hasNext()){
String element = listIterator.next();
System.out.println(element);
}
ListIterator<String> listIterator = list.listIterator(list.size());
while(listIterator.hasPrevious()){
String element = listIterator.previous();
System.out.println(element);
}
用 ListIterator 自带的方法修改数据不会抛出异常
五、Vector 和 Stack类
了解:Vector是元老级别的集合类,在JDK1.0开始。JDK1.2开始才推出集合框架的概念,考虑到当时很多
程序员习惯使用Vector,就让Vector多实现了List接口,这样才将其保留下来。
public class Test01 {
public static void main(String[] args) {
Vector<String> list = new Vector<>();
list.add("麻生希");
list.add("椎名空");
list.add("爱田奈奈");
list.add("三上悠亚");
list.add("明日花绮罗");
int size = list.size();
System.out.println("获取元素的个数:" + size);
list.set(0, "林成");
String elment = list.get(0);
System.out.println("获取指定下标上的元素:" + elment);
list.add(1, "卢永刚");
Vector<String> newList1 = new Vector<>();
Collections.addAll(newList1, "aaa","bbb","ccc","明日花绮罗");
list.addAll(newList1);
Vector<String> newList2 = new Vector<>();
Collections.addAll(newList2, "ddd","eee","fff");
list.addAll(3, newList2);
System.out.println("判断集合中是否包含某个元素:" + list.contains("椎名空"));
Vector<String> newList3 = new Vector<>();
Collections.addAll(newList3, "eee","ddd","fff","ggg");
System.out.println("判断集合中是否包含某个集合中所有元素:" + list.containsAll(newList3));
int index = list.indexOf("椎名空");
System.out.println("获取元素在集合中的下标:" + index);
boolean empty = list.isEmpty();
System.out.println("判断集合中是否没有元素:" + empty);
list.remove(3);
list.remove("eee");
Vector<String> newList4 = new Vector<>();
Collections.addAll(newList4, "fff","aaa","bbb","xxx");
list.removeAll(newList4);
Vector<String> newList5 = new Vector<>();
Collections.addAll(newList5, "林成","卢永刚","椎名空","爱田奈奈","三上悠亚","yyy");
list.retainAll(newList5);
list.set(2, "深田咏美");
List<String> subList = list.subList(1, 3);
Object[] array = subList.toArray();
System.out.println(Arrays.toString(array));
System.out.println("-------------");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("-------------");
for (String element : list) {
System.out.println(element);
}
System.out.println("-------------");
Iterator<String> it = list.iterator();
while(it.hasNext()){
String e = it.next();
System.out.println(e);
}
System.out.println("-------------");
ListIterator<String> listIterator = list.listIterator();
while(listIterator.hasNext()){
String e = listIterator.next();
System.out.println(e);
}
}
}
v.removeElement("林成2");
v.removeElementAt(2);
Enumeration<String> elements = v.elements();
while(elements.hasMoreElements()){
String nextElement = elements.nextElement();
System.out.println(nextElement);
}
Stack 特点:栈模式 - 先进后出
Stack<String> stack = new Stack<>();
stack.push("林成1");
stack.push("林成2");
stack.push("林成3");
stack.push("林成4");
stack.push("林成5");
System.out.println("距离栈顶的位置(从1开始):" + stack.search("林成2"));
while(!stack.empty()){
String element = stack.pop();
System.out.println(element);
}
System.out.println(stack.size());
六、HashSet 类
特点:去重+无序
使用 HashSet 方法,list所有的与下标有关的不能用,其他相同
HashSet<String> set = new HashSet<>();
set.add("麻生希");
set.add("椎名空");
set.add("爱田奈奈");
set.add("三上悠亚");
set.add("明日花绮罗");
int size = set.size();
System.out.println("获取元素的个数:" + size);
HashSet<String> newSet1 = new HashSet<>();
Collections.addAll(newSet1, "aaa","bbb","ccc","明日花绮罗");
set.addAll(newSet1);
System.out.println("判断集合中是否包含某个元素:" + set.contains("椎名空"));
HashSet<String> newSet2 = new HashSet<>();
Collections.addAll(newSet2, "eee","ddd","fff","ggg");
System.out.println("判断集合中是否包含某个集合中所有元素:" + set.containsAll(newSet2));
boolean empty = set.isEmpty();
System.out.println("判断集合中是否没有元素:" + empty);
set.remove("爱田奈奈");
HashSet<String> newSet3 = new HashSet<>();
Collections.addAll(newSet3, "fff","aaa","bbb","xxx");
set.removeAll(newSet3);
HashSet<String> newSet4 = new HashSet<>();
Collections.addAll(newSet4, "林成","卢永刚","椎名空","爱田奈奈","三上悠亚","yyy");
set.retainAll(newSet4);
Object[] array = set.toArray();
System.out.println(Arrays.toString(array));
System.out.println("-------------");
for (String element : set) {
System.out.println(element);
}
System.out.println("-------------");
Iterator<String> it = set.iterator();
while(it.hasNext()){
String e = it.next();
System.out.println(e);
}
七、TreeSet 类
特点:自然排序
知识点:使用TreeSet方法
TreeSet<String> set = new TreeSet<>();
set.add("麻生希");
set.add("椎名空");
set.add("爱田奈奈");
set.add("三上悠亚");
set.add("明日花绮罗");
int size = set.size();
System.out.println("获取元素的个数:" + size);
TreeSet<String> newSet1 = new TreeSet<>();
Collections.addAll(newSet1, "aaa","bbb","ccc","明日花绮罗");
set.addAll(newSet1);
System.out.println("判断集合中是否包含某个元素:" + set.contains("椎名空"));
TreeSet<String> newSet2 = new TreeSet<>();
Collections.addAll(newSet2, "eee","ddd","fff","ggg");
System.out.println("判断集合中是否包含某个集合中所有元素:" + set.containsAll(newSet2));
boolean empty = set.isEmpty();
System.out.println("判断集合中是否没有元素:" + empty);
set.remove("爱田奈奈");
TreeSet<String> newSet3 = new TreeSet<>();
Collections.addAll(newSet3, "fff","aaa","bbb","xxx");
set.removeAll(newSet3);
TreeSet<String> newSet4 = new TreeSet<>();
Collections.addAll(newSet4, "林成","卢永刚","椎名空","爱田奈奈","三上悠亚","yyy");
set.retainAll(newSet4);
Object[] array = set.toArray();
System.out.println(Arrays.toString(array));
System.out.println("-------------");
for (String element : set) {
System.out.println(element);
}
System.out.println("-------------");
Iterator<String> it = set.iterator();
while(it.hasNext()){
String e = it.next();
System.out.println(e);
}
知识点:TreeSet排序
需求:创建两个TreeSet对象,分别存Integer、String,感受排序
TreeSet:自然排序(根据不同的类型,选择不同排序规则)
TreeSet 存 Integer:数字排序
TreeSet 存 String:字典排序
TreeSet<Integer> set1 = new TreeSet<>();
set1.add(5);
set1.add(1);
set1.add(4);
set1.add(2);
set1.add(6);
set1.add(3);
set1.add(3);
for (Integer integer : set1) {
System.out.println(integer);
}
TreeSet<String> set2 = new TreeSet<>();
set2.add("c");
set2.add("d");
set2.add("a");
set2.add("b");
for (String string : set2) {
System.out.println(string);
}
知识点:TreeSet排序
理解二叉树的网站 :https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
需求:创建TreeSet对象,存储Student
Comparable - 内置比较器 : 排序的类需要实现Comparable接口,重写compareTo方法,制定排序规则和重复判断规则。
package com.dream.treeset_class;
public class Student implements Comparable<Student>{
private String name;
private char sex;
private int age;
private String classId;
private String id;
............
@Override
public int compareTo(Student o) {
return this.age - o.age;
}
}
需求:创建TreeSet对象,存储Student,按照名字长度排序,长度一致按照年龄排序
Comparator - 外置比较器 :TreeSet 通过匿名类实现 Comparator 接口,实现比较规则的制定。
TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
if(o1.equals(o2)){
return 0;
}
if(o1.getName().length() != o2.getName().length()){
return o1.getName().length() - o2.getName().length();
}
if(o1.getAge() != o2.getAge()){
return o1.getAge() - o2.getAge();
}
return 1;
}
});
作用:排序时使用
使用场景:
内置比较器:对象要想存入TreeSet、TreeMap中,对象所属的类必须要实现内置比较器
外置比较器:当内置比较的规则不满足现在的需求,但又不能改动内置比较器规则时
) {
return this.age - o.age;
} }
需求:创建TreeSet对象,存储Student,按照名字长度排序,长度一致按照年龄排序
Comparator - 外置比较器 :TreeSet 通过匿名类实现 Comparator 接口,实现比较规则的制定。
```java
TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
if(o1.equals(o2)){
return 0;
}
if(o1.getName().length() != o2.getName().length()){
return o1.getName().length() - o2.getName().length();
}
if(o1.getAge() != o2.getAge()){
return o1.getAge() - o2.getAge();
}
return 1;
}
});
作用:排序时使用
使用场景:
内置比较器:对象要想存入TreeSet、TreeMap中,对象所属的类必须要实现内置比较器
外置比较器:当内置比较的规则不满足现在的需求,但又不能改动内置比较器规则时
优先级别:外置比较器 > 内置比较器
|