1.List有序可重复
新增了一些根据索引操作的方法
创建一个List集合
List<String> list = new ArrayList<>();
<>里面泛指数据类型,例如<>里面存放String,则存储的所有数据类型都是String
遍历方式:
先存放一些String的数据
普通for循环:
for(int i=0;i<=list.size()-1;i++){
System.out.println(list.get(i))
}
增强for循环:
for(String s:list){
System.out.println(s);
}
迭代器:
Iterator<String> it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
2,ArrayList是List接口的实现类
特点:有序 可重复
底层结构: 可变数组
优点: 根据索引查询效率高,访问速度快
缺点: 增删涉及到数组的拷贝问题等效率较低
应用场景: 大量做查询,少量做增删的情况下适合使用ArrayList存储数据
扩容: 初始容量为10,扩容机制->int newCapacity = oldCapacity + (oldCapacity >> 1); 每次扩容原容量的1.5倍,利用Arrays.copyOf实现扩容
新增方法: void forEach(Consumer<? super E> action) 对 Iterable每个元素执行给定操作,直到处理 Iterable所有元素或操作引发异常。
2.2:Vector向量
特点:有序 可重复
底层架构特点与ArrayList相同
Vector与ArrayList区别:
1)ArrayList 线程不安全,不同步->效率较高 Vector 是线程安全,同步 -> 效率较低
2)ArrayList->每次扩容原容量的1.5倍 Vector 每次扩容原容量的2倍,ArrayList更有利于内存的节约
3,LinkedList
特点:有序 可重复
底层结构:双向链表
优点:做查询效率较低
缺点:做增删效率较高
应用场景:大量做增删少量做查询推荐使用LinkedList
新增功能:新增了一些可以操作链表头尾的方法
手写一个LinkedList:简单通过单向链表实现LinkedList容器类型->链表头节点
public class Class005_MyLinkedList {
public static void main(String[] args) {
MyLinkedList list = new MyLinkedList();
list.add("zhangsan");
System.out.println(list.size);
list.add("lisi");
System.out.println(list.size);
System.out.println(list);
System.out.println(list.get(0));
System.out.println(list.get(1));
System.out.println(list.get(2));
}
}
//自定义容器 : 以节点为单位
class MyLinkedList{
//链表头节点
private Node head;
//集合中存储数据的个数
int size;
public MyLinkedList() {
}
/**
* 添加数据的方法
* @param value 要添加的数据
*/
public void add(Object value) {
//创建新节点
Node newNode = new Node(value,null);
//判断是否为链表头节点
if(head==null && size==0){
head = newNode;
//size++
size++;
return;
}
//原链表中存在数据:
//遍历原链表,找到最后一个节点,新节点挂上去
//创建临时变量 : 永远指向判断的新节点
Node temp = head;
while(true){
//死循环结束的条件 当temp指向最后一个节点结束
if(temp.getNext()==null){
break;
}
//temp引用指向下一个新节点
temp = temp.getNext();
}
//temp指向原链表的最后一个节点,新节点挂上去
temp.setNext(newNode);
//size++
size++;
}
/**
* get 根据索引获取数据
* int index 索引
* return 返回对应索引位置的数据
*/
public Object get(int index){
//校验索引
if(index <0 || index>=size){
throw new IndexOutOfBoundsException(index+"索引越界啦!!!");
}
//临界变量
Node temp = head;
//i作为当前链表的索引
for(int i=0;i<size;i++){
if(i == index){
return temp.getData();
}
//指向下一个新节点
temp = temp.getNext();
}
return null;
}
//size() 返回集合中的数据个数
public int size(){
return this.size;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("[");
//遍历链表中的每一个节点,获取到每一个节点的data属性值,拼接到sb中
Node temp = head;
while(temp != null){
//当钱节点的值拼接到sb中
sb.append(temp.getData()+", ");
//temp执行新节点
temp = temp.getNext();
}
//结束的]
sb.delete(sb.length()-2,sb.length());
sb.append("]");
return sb.toString();
}
}
//节点类型
class Node{
//存储数据
private Object data;
//记录下一个节点的地址
private Node next;
public Node() {
}
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
@Override
public String toString() {
return "Node{" +
"data=" + data +
", next=" + next +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Node node = (Node) o;
return Objects.equals(data, node.data) &&
Objects.equals(next, node.next);
}
}
4.Set无序 不可重复,需要去重
新增方法: Set of(E… elements)返回包含任意数量元素的不可修改集。
无序: 存放的顺序与内部真实存储的顺序不一致(内部与自己存储的规则)
去重: 两个数据调用equals方法返回值true,相同需要去重,false不同可以添加
遍历方式:for each |迭代器iterator
5.HashSet
优点:查询.增删效率较高
缺点:无序
去重:需要在存储数据的类型中重写hashcode与equal方法实现数据的去重