2021.10.21
Collection(集合):
继承体系:
常用方法:
package study;
import java.util.ArrayList;
import java.util.Collection;
public class Part01 {
public static void main(String[] args) {
// 创建集合对象
Collection c1 = new ArrayList();
// 判断是否为空(个数是否为0)
System.out.println(c1.isEmpty());
// 集合中是不能保存基本类型的,需要转换为对应包装类才可以
// 这里会进行自动装箱为Integer类型,然后发生多态转型为Object类型 进行存储
c1.add(123);
c1.add(new Integer(1));
c1.add(new Part01());
// 个数
System.out.println(c1.size());
System.out.println(c1.isEmpty());
// 删除,会调用要删除元素的equals方法,但是Integer覆写了,所以可以把1删掉
c1.remove(1);
A a = new A("张三");
A a1 = new A("张三");
c1.add(a);
// 所以使用集合保存自定义类型的时候,要注意,是否要覆写equals方法,定义怎么算相等
c1.remove(a1);
// 把集合转换为数组
Object[] arr = c1.toArray();
for (Object object : arr) {
System.out.println(object);
}
// 清空集合
c1.clear();
System.out.println(c1.size());
}
}
class A{
private String name ;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
A other = (A) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public A(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return "A [name=" + name + "]";
}
}
Contains和Remove注意事项:
Contains(数据) : 判断集合中是否包含某个元素
Remove(数据 ) : 删除指定元素
两个方法底层都会自动调用该对象的equals方法
因为不管是判断是否包含还是删除,都要先找到这个数据,而找到只能比较
但是集合中保存的都是引用类型,所以比较只能使用equals方法
所以如果存储的是自定义类型,就要考虑equals方法的覆写问题
package study;
import java.util.Collection;
import java.util.Iterator;
import java.util.linkedList;
public class Part02 {
public static void main(String[] args) {
// Collection c1 = new ArrayList();
// Collection c1 = new HashSet();
Collection c1 = new linkedList();
c1.add(1);
c1.add("abc");
// 判断是否包含
System.out.println(c1.contains(1));
// 1 创建迭代器
Iterator it = c1.iterator();
// 遍历 判断下面是否有元素
while (it.hasNext()) {
// 获取并指向下一个元素
Object obj = it.next();
System.out.println(obj);
}
// 使用完之后,想再次使用,需要重新创建
it = c1.iterator();
// 迭代器创建之后,不能添加和删除 , 必须重新生成迭代器
c1.add(2);
c1.add(3);
c1.remove(1);
it = c1.iterator();
while (it.hasNext()) {
// 获取并指向下一个元素
Object obj = it.next();
System.out.println(obj);
// 使用迭代器的时候,不能更改集合个数,所以删除数据的时候不能使用集合的删除,应该使用迭代器的删除
// c1.remove(obj);
it.remove();
}
System.out.println(c1.size() + "----");
}
}
list类:
package study;
import java.util.ArrayList;
import java.util.List;
public class Part03 {
public static void main(String[] args) {
// 创建对象
// Vector 已经过时了,ArrayList是Vector的升级版,Vector是线程安全,而ArrayList是非线程安全的
List list = new ArrayList();
list.add(100);
list.add(123);
// [100, 123] 覆写了toString方法
System.out.println(list);
}
}
ArrayList:
package study;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Part04 {
public static void main(String[] args) {
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
// add(E e ) : 尾部添加
// add(int index , E e ) : 添加到指定位置
// set(int index, E e ) : 更改指定位置上的元素值
// remove(Object object) : 根据元素内容删除
// remove(int index) : 根据索引删除
// get(int index) : 获取指定位置的数据
list.add(1, 4);
list.set(3, 33);
System.out.println(list.get(2));
// 这是根据索引删除
list.remove(1);
// 删除元素值为1
list.remove(new Integer(1));
System.out.println(list);
// 传统for遍历
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// foreach遍历
for (Object object : list) {
System.out.println(object);
}
// 迭代器遍历
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
package study;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Part05 {
public static void main(String[] args) {
List list = new ArrayList();
list.add(4);
list.add(1);
list.add(2);
list.add(14);
list.add(6);
Collections.sort(list);
System.out.println(list);
}
}
linkedList:
package study;
import java.util.Iterator;
import java.util.linkedList;
public class Part06 {
public static void main(String[] args) {
linkedList list = new linkedList();
// add(E e ) : 尾部添加
// add(int index , E e ) : 添加到指定位置
// set(int index, E e ) : 更改指定位置上的元素值
// remove(Object object) : 根据元素内容删除
// remove(int index) : 根据索引删除
// get(int index) : 获取指定位置的数据
// 首部添加
list.addFirst(1);
// 首部添加
list.push(11);
// 首部添加 成功返回true
list.offerFirst(111);
// 尾部添加
list.addLast(2);
// 尾部添加 成功返回true
list.offerLast(22);
// 尾部添加 成功返回true
list.offer(222);
// 上面这几个方法 没啥区别,本质就是 linkLast 和 linkFirst
list.add(1);
list.add(2);
list.add(3);
list.add(0, 4);
list.set(3, 33);
System.out.println(list.get(2));
// 这是根据索引删除
list.remove(1);
// 删除元素值为1
list.remove(new Integer(1));
System.out.println(list);
// 传统for遍历
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// foreach遍历
for (Object object : list) {
System.out.println(object);
}
// 迭代器遍历
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
linkedList 的底层逻辑:
从源码中可以看到,linkedList的底层时使用,链表来实现的。每一个linkedList对象都持有一个first,一个last指针,他们分别指向链表的第一个节点和最后一个节点。而且从节点(Node)的数据结构来看的话,一个节点有两个指针域,一个next,一个prev,分指向该节点的后继和前驱,item是数据域。这样看来的话linkedList的底层是用双向链表实现的无疑了。我们都知道链表的特点就是适合插入(不需要移动元素,只需要改变一下指针指向就可以了)元素,不适合查找(查找第i个元素必须从第一个元素开始遍历,直到找到第i个元素为止,当然这里面用了一个二分法,使得速度稍微快了点)元素的.
package study;
import java.util.linkedList;
public class Part07 {
public static void main(String[] args) {
// size = 0 , f = null , l = null
linkedList list = new linkedList();
// size = 1 , f = a , l = a
list.add("a");
list.add("b");
list.add("c");
list.add("e");
list.add("f");
list.add("q");
System.out.println(list.get(2));
}
}



