Day18 容器1(集合框架)

容器(集合框架)

这里写图片描述
为什么使用集合框架?
这里写图片描述

Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util包中
面向接口编程
1、接口
这里写图片描述
2、具体类
3、算法
这里写图片描述

Collection接口的常用方法

集合作为容器应该具有的功能(增,删,改,查),
不一定全有。
集合的基本操作:增加,删除,判断,取出
这里写图片描述
List与Set接口
这里写图片描述
Map接口存储一组键值对象,提供key到value的映射

List接口的实现类:

List特点:有序,不唯一(可重复)
这里写图片描述
ArrayList实现了长度可变的数组,在内存中分配连续的空间。
优点:遍历元素和随机访问元素的效率比较高
缺点:添加和删除需要大量移动元素效率低,按照内容查询效率低
这里写图片描述
LinkedList采用链表存储方式。
优点:插入、删除元素时效率比较高
缺点:遍历和随机访问元素效率低下
这里写图片描述
List接口特有的方法:

这里写图片描述
注意:获取List长度用size()方法

List<String> list = new ArrayList<>();//<String>规定只能装String类型
        list.add("java");
        list.add("html");
        list.add("css");
        list.add("java");
        System.out.println(list);
ArrayList

ArrayList的增删查改
实现了List接口,ArrayList中允许存在Null元素,此实现不是同步的(效率高)
Vector(线程安全,效率低)
list接口继承Collection 继承 Iterable
以及容器中所有元素的遍历
调用list.add的时候才有初始容量,刚new的时候size是0
构造方法:
ArrayList()
构造一个初始容量为 10 的空列表。
ArrayList(Collection< ? extends E> c)
构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
ArrayList(int initialCapacity)
构造一个具有指定初始容量的空列表。

成员方法:

boolean add(E e)
将指定的元素添加到此列表的尾部。
void add(int index, E element)
将指定的元素插入此列表中的指定位置。
boolean addAll(Collection< ? extends E> c)
按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。
boolean addAll(int index, Collection< ? extends E> c)
从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。
void clear()
移除此列表中的所有元素。
Object clone()
返回此 ArrayList 实例的浅表副本。
boolean contains(Object o)
如果此列表中包含指定的元素,则返回 true。
void ensureCapacity(int minCapacity)
如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。
E get(int index)
返回此列表中指定位置上的元素。
int indexOf(Object o)
返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。
boolean isEmpty()
如果此列表中没有元素,则返回 true
int lastIndexOf(Object o)
返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。
E remove(int index)
移除此列表中指定位置上的元素。
boolean remove(Object o)
移除此列表中首次出现的指定元素(如果存在)。
protected void removeRange(int fromIndex, int toIndex)
移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。
E set(int index, E element)
用指定的元素替代此列表中指定位置上的元素。
int size()
返回此列表中的元素数。
Object[] toArray()
按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。

void trimToSize()
将此 ArrayList 实例的容量调整为列表的当前大小。

测试代码:

public class Test1 {

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
    /*  Collection<String> collection = new ArrayList<>();
        Iterable<String> iterable = new ArrayList<>();*/
        //增加元素   add()  insert()
        list.add("one");
        list.add(1, "two");
        list.add(list.size(),"three");
        //将自身所有的元素在加一遍
        list.addAll(list);
        System.out.println(list);
        //查询元素
        System.out.println("是否包含one:"+list.contains("one"));
        System.out.println("one的索引值:"+list.indexOf("one"));
        System.out.println("最后一个one的索引值:"+list.lastIndexOf("one"));
        //修改元素
        list.set(3, "four");
        System.out.println(list);
        //删除元素  remove   delete
        list.remove(0);//删除索引值为0的元素
        list.remove("two");//删除容器中第一个与目标元素相同的元素
        System.out.println(list);
        //打印第一个元素
        System.out.println("第一个元素:"+list.get(0));

        //容器的遍历方式
        showArrayList(list);
    }
    /**
     * 展示容器内所有元素
     * @param list
     */
    public static void showArrayList(List<String> list) {
        //1.for循环
        /*for(int i = 0;i < list.size();i++){
            System.out.println(list.get(i));
        }
        //2.for-each
        for (String string : list) {
            System.out.println(string);
        }*/
        //3.迭代器  Iterator
        //获取指向容器首个元素迭代器
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

}
Vector
  • Vector:

    • 底层为对象数组
    • Object[]data
    • 可以实现可增长的对象数组
    • Vector 是同步的 (jdk1.0)

      • 构造方法:
    • 默认初始容量为10

      • 成员方法:
    • 增加
    • add(E e)
    • add(int index,E e)
    • addAll()
    • addAll(int index,Colleaction< ? extends E> collection)
    • void insertElementAt(E obj, int index)
      将指定对象作为此向量中的组件插入到指定的 index 处
    • 删除
    • E remove(int index)
      移除此向量中指定位置的元素。
      boolean remove(Object o)
      移除此向量中指定元素的第一个匹配项,如果向量不包含该元素,则元素保持不变。
      boolean removeAll(Collection< ?> c)
      从此向量中移除包含在指定 Collection 中的所有元素。
      void removeAllElements()
      从此向量中移除全部组件,并将其大小设置为零。
      boolean removeElement(Object obj)
      从此向量中移除变量的第一个(索引最小的)匹配项。
      void removeElementAt(int index)
      删除指定索引处的组件。
      protected void removeRange(int fromIndex, int toIndex)
      从此 List 中移除其索引位于 fromIndex(包括)与 toIndex(不包括)之间的所有元素
      clear();

    • 修改

    • E set(int index, E element)
      用指定的元素替换此向量中指定位置处的元素。
      void setElementAt(E obj, int index)
      将此向量指定 index 处的组件设置为指定的对象。

    • 查询

    • contains()
    • indexOf()
    • lastIndexOf()
    • 遍历
    • 1.for循环
    • 2.for-each
    • 3.迭代器

    测试代码:

public class TestVector {

    public static void main(String[] args) {
        Vector<String> vector = new Vector<>();
        vector.add("one");
        vector.insertElementAt("zero", 0);
        vector.addElement("two");
        System.out.println(vector);
        //
        /*vector.removeElementAt(0);
        System.out.println(vector);
        vector.remove(0);
        System.out.println(vector);
        vector.remove("two");
        System.out.println(vector);
        vector.removeAllElements();
        vector.clear();*/
        //修改
        vector.set(0, "零");
        vector.setElementAt("壹", 1);
        System.out.println(vector);

        //是否包含零
        System.out.println("是否包含零:"+vector.contains("零"));
        System.out.println("零的索引值:"+vector.indexOf("零"));

        showVector(vector);


    }
    /**
     * 展示容器vector中所有的元素
     * @param vector
     */
    public static void showVector(Vector<String> vector){
        //1.for循环
        for (int i = 0; i < vector.size(); i++) {
            //根据索引值获取元素
            System.out.println(vector.get(i));
            //vector特有的方法
            System.out.println(vector.elementAt(i));
        }
        //2.for-each
        for (String string : vector) {
            System.out.println(string);
        }
        //3.迭代器
        //a.获取指向容器的迭代器
        Iterator<String> iterator = vector.iterator();
        //Iterator<String> iterator1 = vector.listIterator();
        //b.让迭代器迭代,知道没有下一个元素为止
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

}
泛型

为什么需要泛型
解决数据类型操作不统一产生的异常
使用泛型可以更好的去保护数据类型
用处:
1.接口定义的时候

public interface<E>{

 }

2.类定义的时候

public class Student<K,V>{
        public void show(K key1,V value1){
        }
  }

3.方法的定义中(前提类中已经定义了该泛型)

public void show(K key1,V value1){
        }

4.上界控制

<? extends Student>

5.下界控制

<? super Student>

测试代码:

public class Test2 {

    public static void main(String[] args) {

        /*List<SuperClass> list = new ArrayList<>();
        showList(list);
        List<Object> list2 = new ArrayList<>();
        //这种写法报错,上界控制的时候,只能放SuperClass或者是SuperClass的子类
        showList(list2);
        */
        //下界控制
        List<SuperClass> list3 = new ArrayList<>();
        showList1(list3);
        List<Object> list4 = new ArrayList<>();
        showList1(list4);
        List<SubClass> list5 = new ArrayList<>();
        //这种写法报错,下界控制的时候,只能放SuperClass或者是SuperClass的父类
        //showList1(list5);

    }

    public static void showList(List<? extends SuperClass> list){

    }
    //下界控制
    public static void showList1(List<? super SuperClass> list){

    }

}

父类:

public class SuperClass {

}

子类:


public class SubClass extends SuperClass{

}
模拟系统类实现List的面向接口编程

自定义接口:

public interface MyList <E>{
    int size();
    void add(E e);
    E get(int index);
    void set(int index,E e);

}

子类实现接口:

public class MyArrayList<E> implements MyList<E>{
    private Object[]elementData;
    private int size;
    public MyArrayList() {
        this(10);
    }
    public MyArrayList(int initSize) {
        if(initSize < 0) throw new IllegalArgumentException("非法参数");
        elementData = new Object[initSize];
    }

    @Override
    public void add(E e) {
        elementData[size++] = e;
    }

    @SuppressWarnings("unchecked")
    @Override
    public E get(int index) {
        if(index < 0 || index >= size) throw new IllegalArgumentException("非法参数");
        return (E) elementData[index];
    }

    @Override
    public void set(int index, E e) {
        if(index < 0 || index >= size) throw new IllegalArgumentException("非法参数");
        elementData[index] = e;
    }
    @Override
    public int size() {
        return this.size;
    }
}

测试代码:

public class Test1 {

    public static void main(String[] args) {
        //接口指向实现类
        MyList<String> list = new MyArrayList<>(10);
        list.add("zero");
        list.add("one");
        list.set(0, "two");
        showMyArrayList(list);

    }
    /**
     * 展示自定义容器中所有的方法
     * @param list
     */
    public static void showMyArrayList(MyList<String>list) {
        for(int i = 0;i < list.size();i++){
            System.out.println(list.get(i));
        }
    }
}
LinkedList

LinkedList
链表
除了实现List接口之外,Deque(队列接口)

元素有序,不唯一;允许NUll元素,此实现不是同步的。
构造方法:
LinkedList()
构造一个空列表。
成员方法:

add()
addFirst()
addLast()

offer()
offerFirst()
offerLast()
push(E e)

E remove()
获取并移除此列表的头(第一个元素)。
E remove(int index)
移除此列表中指定位置处的元素。
boolean remove(Object o)
从此列表中移除首次出现的指定元素(如果存在)。
E removeFirst()
移除并返回此列表的第一个元素
E removeLast()
移除并返回此列表的最后一个元素
E poll()
获取并移除此列表的头(第一个元素)
E pollFirst()
获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
E pollLast()
获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。
E pop()
从此列表所表示的堆栈处弹出一个元素。


contains();
indexOf();

E set(int index, E element)
将此列表中指定位置的元素替换为指定的元素。

迭代:
Iterator descendingIterator()
返回以逆向顺序在此双端队列的元素上进行迭代的迭代器。
ListIterator listIterator(int index)
返回此列表中的元素的列表迭代器(按适当顺序),从列表中指定位置开始。
测试代码:

public class TestLinkedList {

    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<>();
//      Queue<String> queue = new LinkedList<>();
//      Deque<String> deque = new LinkedList<>();
        list.add("one");
        list.add("two");
        list.add("three");

        list.set(0, "一");
        System.out.println(list);
        //根据值删除
        /*if(list.contains("一")){
            list.remove("一");
        }*/
        //根据索引值删除
        int index = list.indexOf("一");
        if(index >= 0){
            list.remove(index);
        }
        showLinkedList(list);
    }
    /**
     * 遍历LinkedList中的所有元素
     * @param lkList
     */
    public static void showLinkedList(List<String>lkList) {
        //1.for循环
        for(int i = 0;i < lkList.size();i++){
            System.out.println(lkList.get(i));
        }
        //2.for-each
        for (String string : lkList) {
            System.out.println(string);
        }
        //3.迭代器
        Iterator<String> iterator = lkList.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

}
Iterator

所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现了Iterator接口的对象。
Iterator对象称作迭代器,用以方便的实现对容器内元素的遍历操作。
Iterator接口定义了如下方法:
boolean hasNext(); //判断是否有元素没有被遍历
Object next(); //返回游标当前位置的元素并将游标移动到下一个位置
void remove(); //删除游标左面的元素,在执行完next之后该
//操作只能执行一次
所有的集合类均未提供相应的遍历方法,而是把遍历交给迭代器完成。迭代器为集合而生,专门实现集合遍历

Iterator是迭代器设计模式的具体实现

Iterator方法
boolean hasNext():判断是否存在另一个可访问的元素
Object next():返回要访问的下一个元素
void remove():删除上次访问返回的对象

可以使用Iterator遍历的本质是什么?
实现Iterable接口

为什么不使用for增强;
For-each循环
增强的for循环,遍历array或Collection的时候相当简便
无需获得集合和数组的长度,无需使用索引访问元素,无需循环条件
遍历集合时底层调用Iterator完成操作

For-each缺陷
数组:
不能方便的访问下标值
不要在for-each中尝试对变量赋值,只是一个临时变量
集合:
与使用Iterator相比,不能方便 的删除集合中的内容

For-each总结
除了简单的遍历并读出其中的内容外,不建议使用增强for

使用迭代器例子:
arrayList:

//3.迭代器  Iterator
        //获取指向容器首个元素迭代器
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
为什么需要ListIterator

在迭代过程中,准备添加或者删除元素

ArrayList al=new ArrayList();
al.add("java1");//添加元素
al.add("java2");
al.add("java3");
//遍历
Iterator it=al.iterator();
while(it.hasNext()){
       Object obj=it.next();
       if (obj.equals("java2")) {
        al.add("java9");
       }
      sop("obj="+obj);
}

ListIterator的作用->解决并发操作异常
在迭代时,不可能通过集合对象的方法(al.add(?))操作集合中的元素,
会发生并发修改异常。
所以,在迭代时只能通过迭代器的方法操作元素,但是Iterator的方法
是有限的,只能进行判断(hasNext),取出(next),删除(remove)的操作,
如果想要在迭代的过程中进行向集合中添加,修改元素等就需要使用
ListIterator接口中的方法

ListIterator li=al.listIterator();
while(li.hasNext()){
     Object obj=li.next();
     if ("java2".equals(obj)) {
            li.add("java9994");
            li.set("java002");
      }
}
sop(al);

判断前边是否有元素
这里写图片描述

小结

ArrayList
遍历元素和随机访问元素的效率比较高
插入、删除等操作频繁时性能低下

Vector

LinkedList
插入、删除元素时效率较高
查找效率较低

迭代器
泛型
遍历arrayList和linkedList的三种方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值