JAVA - 集合【List ArrayList LinkedList】

集合和数组:

  • 集合和数组相似点
    1. 都可以存储多个对象,对外作为一个整体存在
  • 数组的缺点
    1. 数组缺乏封装,操作繁琐
    2. 数组无法直接保存映射关系
    3. 数组采用连续存储空间,删除和添加效率低下
    4. 长度必须在初始化时指定,且固定不变

集合框架

  • Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util包中。存放在集合中的数据,被称为元素(element)
  • 集合架构
    • Collection 接口存储一组不唯一,无序的对象
    • List 接口存储一组不唯一,有序(索引顺序)的对象
    • Set 接口存储一组唯一,无序的对象
    • Map接口存储一组键值对象,提供key到value的映射
      • Key 唯一 无序     
      • value  不唯一 无序

List的主要实现类

  • List
    • 特点:有序  不唯一(可重复)
  • ArrayList
    • 在内存中分配连续的空间,实现了长度可变的数组
    • 优点:遍历元素和随机访问元素的效率比较高
    • 缺点:添加和删除需大量移动元素效率低,按照内容查询效率低

【示例1】使用ArrayList存储多个学生的分数

public class TestArrayList1 {
    public static void main(String[] args) {
        //创建一个ArrayList对象
        ArrayList list = new ArrayList();        
        //向集合中添加多个分数
        list.add(78); //加到最后  
        list.add(89);
        list.add(56);
        //list.add(new Integer(56));
        list.add(89);
        list.add(2, 100);//加到指定位置  底层发生了元素大量后移
        //list.add(10,20);
        ArrayList list2 = new ArrayList();
        list2.add(60);
        list2.add(58);
        list2.add(29);
        //list.addAll(list2);
        list.addAll(0, list2);        
        //输出集合中分数
        System.out.println(list.size());//4
        System.out.println(list);//[]
        //遍历1:使用for循环
        System.out.println("遍历1:使用for循环");
        for(int i=0;i<list.size();i++){
            //获取第i个元素
            int elem = (Integer)list.get(i);//自动拆箱
            //输出第i个元素
            System.out.println(i+"    "+elem);
        }
        //遍历2:使用增强的for循环
        System.out.println("遍历2:使用增强的for循环");
        for(Object elem :list){
            //System.out.println(elem);
            Integer i = (Integer)elem;
            System.out.println(i);
        }
        //遍历3:使用Iterator迭代器
        System.out.println("遍历3:使用Iterator迭代器");
        Iterator it = list.iterator();
        while(it.hasNext()){//还有元素,没有就结束循环
            //如果有,就取出来
            int elem = (Integer)it.next();            
            //输出来
            System.out.println(elem);        }
    }
}

【示例2】使用泛型保证集合操作的安全和简便 

public class TestArrayList2 {
    public static void main(String[] args) {
        //创建一个ArrayList对象
        ArrayList<Integer> list = new ArrayList<Integer>();
        //向集合中添加多个分数
        list.add(78); //加到最后  
        list.add(89);
        list.add(56);
        //list.add(new Integer(56));
        list.add(89);
        list.add(2, 100);
        //list.add(10,20);
        ArrayList<Integer> list2 = new ArrayList<Integer>();
        list2.add(60);
        list2.add(58);
        list2.add(29);
        list.addAll(0, list2);
        //输出集合中分数
        System.out.println(list.size());//4
        System.out.println(list);//[]
        
        //遍历1:使用for循环
        System.out.println("遍历1:使用for循环");
        for(int i=0;i<list.size();i++){
            //获取第i个元素
            int elem = list.get(i);//自动拆箱
            //输出第i个元素
            System.out.println(i+"    "+elem);
        }
        //遍历2:使用增强的for循环
        System.out.println("遍历2:使用增强的for循环");
        for(Integer elem :list){
            System.out.println(elem);
            //Integer i = (Integer)elem;
            //System.out.println(i);
        }
        //遍历3:使用Iterator迭代器
        System.out.println("遍历3:使用Iterator迭代器");
        Iterator<Integer> it = list.iterator();
        while(it.hasNext()){//还有元素,没有就结束循环
            //如果有,就取出来
            int elem = it.next();
            //输出来
            System.out.println(elem);
        }
    }
}

 【示例3】ArrayList类的更多方法

public class TestArrayList3 {
    public static void main(String[] args) {
        //创建一个ArrayList对象
        ArrayList<Integer> list = new ArrayList<Integer>();        
        //向集合中添加多个分数
        list.add(78); //加到最后  
        list.add(89);
        list.add(56);        
        //删除
        //list.remove(0);
        list.remove(new Integer(78));        
        //更新
        list.set(1, 65);        
        //输出集合中分数
        //list.clear();
        System.out.println(list.contains(65));
        System.out.println(list.toString());
        //list.ensureCapacity(100);
    }
}
  • LinkedList
    • 采用双向链表存储方式。
    • 缺点:遍历和随机访问元素效率低下

优点:插入、删除元素效率比较高(但是前提也是必须先低效率查询才可。如果插入删除发生在头尾可以减少查询次数)

public class TestLinkedList {
    public static void main(String[] args) {
        //1.创建一个ArrayList集合对象
        //ArrayList<Integer> list = new ArrayList<Integer>();
        //LinkedList<Integer> list = new LinkedList<Integer>();
        //List<Integer> list = new ArrayList<Integer>();
        List<Integer> list = new LinkedList<Integer>();
        //2.对集合中的元素进行操作
        //2.1 添加
        list.add(80);//向末尾添加元素
        list.add(80);
        list.add(78);//自动装箱
        list.add(new Integer(78));
        //list.add("Java");
//        list.addFirst(12);
//        list.addLast(12);
        list.add(0,12);
        list.add(12);
        list.add(100);
        list.add(56);
        list.add(80);
        list.add(2,99);//向指定的位置添加元素
        //2.2 查询指定的元素
        System.out.println(list.size());//元素的个数
        System.out.println(list);
        list.remove(1);
        System.out.println(list);
        System.out.println(list.isEmpty());
    }
}

问题1:将ArrayList替换成LinkedList之后,不变的是什么?

  • 运算结果没有变
  • 执行的功能代码没有变

问题2:将ArrayList替换成LinkedList之后,变化的是什么?

  • 底层的结构变了

    ArrayList:数组     LinkedList:双向链表

  • 具体的执行过程变化了 list.add(2,99)

    ArrayList:大量的后移元素  

LinkedList:不需要大量的移动元素,修改节点的指向即可

问题3:到底是使用ArrayList还是LinkedList

  • 根据使用场合而定
  • 大量的根据索引查询的操作,大量的遍历操作(按照索引0--n-1逐个查询一般),建议使用ArrayList
  • 如果存在较多的添加、删除操作,建议使用LinkedList

问题4:LinkedList增加了哪些方法

  • 增加了对添加、删除、获取首尾元素的方法
  • addFirst()、addLast()、removeFirst()、removeLast()、getFirst()、getLast()、

方法摘要

 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()   从列表中移除所有元素(可选操作)。

 boolean

contains(Object o)  如果列表包含指定的元素,则返回 true。

 boolean

containsAll(Collection<?> c) 
          如果列表包含指定 collection 的所有元素,则返回 true。

 E

get(int index) 返回列表中指定位置的元素。

 boolean

isEmpty()  如果列表不包含元素,则返回 true。

 Iterator<E>

iterator()  返回按适当顺序在列表的元素上进行迭代的迭代器。

 E

remove(int index) 
          移除列表中指定位置的元素(可选操作)。

 boolean

remove(Object o) 
          从此列表中移除第一次出现的指定元素(如果存在)(可选操作)。

 boolean

removeAll(Collection<?> c) 
          从列表中移除指定 collection 中包含的其所有元素(可选操作)。

 boolean

retainAll(Collection<?> c) 
          仅在列表中保留指定 collection 中所包含的元素(可选操作)。

 E

set(int index, E element) 

 用指定元素替换列表中指定位置的元素(可选操作)。

 int

size()  返回列表中的元素数。

 Java中栈和队列的实现类:

Deque和Queue的实现类
 1.ArrayDeque  顺序栈  数组
 2.LinkedList  链栈  链表 

理解Java中栈和队列的接口和实现类:

/**
 * push:入栈
 * pop:出栈
 * peek:获取栈顶元素
*/
public class TestLinkedList2 {
    public static void main(String[] args) { 
        //摞盘子
        Deque<String> deque1 = new LinkedList<String>();
        deque1.push("盘子1");
        deque1.push("盘子2");
        deque1.push("盘子3");

        System.out.println(deque1.size());
        System.out.println(deque1.peek());//get 获取栈顶元素,不移除
        System.out.println(deque1.peek());//get 获取栈顶元素,不移除
        while(!deque1.isEmpty()){
            String elem = deque1.pop();
            System.out.println(elem);
        }
        System.out.println(deque1.size());
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值