【JavaSE】之集合框架(上)

简介: 【JavaSE】之集合框架(上)

前言


本文为Java集合框架相关知识,Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~


一、集合框架体系


02b4e62d56c64e8fb3d41d42238b05a9.png

ef1a26e67a3348fea60ea18fc87d7c7a.png

二、List


1.数组扩容

// 扩容方法和位运算
public class Demo01 {
    public static void main(String[] args) {
        int[] arr= new int[4];
        arr[0] = 10;
        arr[1] = 11;
        arr[2] = 12;
        arr[3] = 13;
        arr = grow(arr);
        System.out.println(arr.length);
    }
    public static int[] grow(int[] arr){
        //int[] newArr = new int[arr.length+arr.length/2];
        //  >>1  位运算  二进制向右移一位变成原来的 一半
        //  1<<          二进制向左移一位变成元的的 一倍
        int[] newArr = new int[arr.length+arr.length>>1];
        /**
           方法一:
         */
        for (int i = 0; i < arr.length; i++) {
            newArr[i] = arr[i];
        }
        /**
         *  方法二:
         */
        System.arraycopy(arr , 0 ,newArr,0,arr.length);
        /**
         *  方法三:
         */
        newArr = Arrays.copyOf(arr, arr.length+arr.length/2);
        return newArr;
    }
}


2.迭代器 : 只服务于Collection接口下的集合


Iterator


  • hasNext() 如果迭代具有更多元素,则返回 true 。
  • next() 返回迭代中的下一个元素。
  • remove() 从底层集合中删除此迭代器返回的最后一个元素(可选操作)。
    // 使用Iterator 迭代器
    public static void print(ArrayList<Person> list){
        Iterator<Person> iterator = list.iterator();
        while (iterator.hasNext()){
            Person person = iterator.next();
            System.out.println(person.getName() + "\t" + person.getAge());
        }
    }

ListIterator


void add(E e) :将指定的元素插入列表(可选操作)。

boolean hasNext():如果此列表迭代器在向前方向遍历列表时具有更多元素,则返回 true 。

boolean hasPrevious():如果此列表迭代器在相反方向遍历列表时具有更多元素,则返回 true 。

E next() 返回列表中的下一个元素,并且前进光标位置。

int nextIndex() 返回由后续调用返回的元素的索引 next() 。

E previous()返回列表中的上一个元素,并向后移动光标位置。

int previousIndex() 返回由后续调用返回的元素的索引 previous()。

void remove() 从列表中删除 next()或 previous() (可选操作)返回的最后一个元素。

void set(E e) 用指定的元素(可选操作)替换 next()或 previous()返回的最后一个元素。

public static void itRepeat(ArrayList<Person> list){
        System.out.println("去除重复元素:");
        // 使用ListIterator 接口可以实现从指定位置迭代集合
        ListIterator<Person> iterator;
        for (int i = 0; i < list.size() ; i++) {
           iterator = list.listIterator(i+1);
           while (iterator.hasNext()){
               Person person = iterator.next();
               if (list.get(i).equals(person)){
                   iterator.remove();
                   System.out.println("即将被删除:..."+person);
               }
           }
        }
    }


terator VS ListIterator


ListIterator有add()方法,可以向List中添加对象,而Iterator没有

ListIterator和Iterator都有hasNext() 和 next() 方法,但ListIterator可以实现指定位置遍历,并且可以顺序遍历和逆序遍历。

ListIterator有set方法,可以在遍历中修改对象。


3.ArrayList


有序可重复 ,底层是动态数组实现 —— 线程不安全

添加数据,如果是基本数据类型会自动装箱为包装类,第一次添加数组长度为10

存储的数据超过数组长度,会自动进行数组扩容,扩容为原来的1.5倍

集合长度有限,最大容量默认为: Integer.MAX_VALUE-8

为什么空8位出来: 1、存储Headerwords;2、避免一些机器内存溢出,减少出错几率,所以少分配;3、最大还是能支持到Integer.MAX_VALUE(2^31 -1)

 public class Test{
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        // 1、添加元素  ——  如果数据是基本数据类型会自动装箱为包装类
        list.add(1);
        list.add("a");
        list.add(true);
        list.add(10.1);
        list.add(2);
        // 2、删除元素 —— 根据下标删除
        list.remove(1);
        // 根据对象删除
        list.remove(new Integer(2));
        // 3、修改
        list.set(1,"b");
        // 4、遍历集合
        print(list);
    }
    public static void print(ArrayList list){
        System.out.println("-------- for循环 ----------");
        for (int i = 0; i < list.size() ; i++) {
            System.out.print(list.get(i) + "\t");
        }
        System.out.println();
        System.out.println("=========== 迭代器循环 =========");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.print(iterator.next() + "\t");
        }
        System.out.println();
    }
}

4.LinkedList


  • 底层是 双向链表 实现 —— 线程不安全
  • 第一次添加对象,把对象添加到Node节点中,falst指向第一个节点,不存在索引
  • 集合长度无限


//  创建 LinkedList 对象
LinkedList list = new LinkedList();
list.add("111"); //添加一个新元素,默认尾部添加
list.add("222");
list.add("333");
list.addFirst("444"); //在头部添加一个新元素
list.addLast("555"); //在尾部添加一个新元素
Object data1=list.removeFirst(); //移除头部元素并返回值
System.out.println(data1); 
Object data2=list.removeLast(); //移除尾部元素并返回值
System.out.println(data2);
list.getFirst(); // 获取头部元素并返回值
list.getLast(); // 获取尾部元素并返回值
for(Object object : list){
    System.out.println(object);
}
//  其他方法的使用与 ArrayList一致


5. ArrayList和LinkedList的区别


数据结构的实现不同。 ArrayList是动态数组实现,LinkedList是双向链表实现

List item查询的效率。ArrayList有下标查询速度快,而LinkedList底层是链表结构,查询需从头开始依次往下查找


增删的效率。在排除增删前后两头的情况下,LinkedList的速度比ArrayList的快,因为LinkedList的添加和删除节点,只要其他节点的前驱后继指引值发生变化,而ArrayList增加删除会更改数组的结构


6.foreach的本质


  • 使用foreach来遍历集合的话,本质上是将其转换为迭代器来使用


System.out.println("=========== foreach循环 =========");
for (Object obj:list) {
    System.out.print(obj+"\t");
}
System.out.println();
// 等价于下边代码
System.out.println("=========== foreach循环 =========");
Iterator iterator = list.iterator();
while(iterator.hasNext()) {
    Object obj = iterator.next();
    System.out.print(obj+"\t");
}

7.Vector


  • 数组结构实现,查询快、增删慢。
  • JDK1.0版本,线程安全、运行效率比ArrayList较慢。
public class TestVector {
    public static void main(String[] args) {
        //创建集合
        Vector vector=new Vector<>();
        //1添加元素
        vector.add("草莓");
        vector.add("芒果");
        vector.add("西瓜");
        System.out.println("元素个数:"+vector.size());
        //2删除
//        vector.remove(0);
//        vector.remove("西瓜");
//        vector.clear();
        //3遍历
        //使用枚举器
        Enumeration en=vector.elements();
        while(en.hasMoreElements()) {
            String  o=(String)en.nextElement();
            System.out.println(o);
        }
        //4判断
        System.out.println(vector.contains("西瓜"));
        System.out.println(vector.isEmpty());
        //5vector其他方法
        //firsetElement、lastElement、elementAt();        
    }
}

8.Stack


  • 模拟 栈 的实现 —— 底层用数组存储数据
  • 特点是:先进后出
public class Demo05 {
    public static void main(String[] args) {
        Stack stack = new Stack();
        // 添加元素
        // Stack类的add方法与push方法区别:
        //         add方法返回的是boolean类型的值
        //         push方法返回的是当前添加的元素
        stack.push("a");
        stack.push("b");
        stack.add("c");
        stack.push("d");
        // 集合中的元素个数
        System.out.println(stack.size());
        // 弹出栈顶元素
        System.out.println(stack.pop());
        System.out.println(stack.pop());
    }
}


三、Queue


1.队列的定义


队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。

队列是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。

队头(first):允许删除的一端,又称队首。

队尾(Rearlsat:允许插入的一端。

空队列:不包含任何元素的空表。


2.队列的使用

public class Demo01 {
    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<>();
        queue.add("小明"); // 向队列添加元素,当队列满时,add方法抛出unchecked异常,而offer方法返回false。
        queue.offer("小黑");
        queue.offer("小蓝");
        queue.offer("小而");
        // 集合中的个数 
        System.out.println(queue.size()); // 4
        // 查询头部元素:如果队列为空,element方法会抛出异常,peek方法会返回null
        System.out.println(queue.element()); // 小明
        System.out.println(queue.peek()); // 小明
        // 打印队列头  
        System.out.println(queue.poll()); // 小明 ,如果队列为空,remove方法会抛出异常,poll方法会返回null。
        System.out.println(queue.size()); // 3
        System.out.println(queue.remove()); // 小黑
    }
}


相关文章
|
Java 编译器
【JAVASE】类与对象 下
【JAVASE】类与对象
|
Java 编译器
【JAVASE】类与对象 中
【JAVASE】类与对象
|
存储 Java 编译器
【javaSE】 类和对象详解(下)
【javaSE】 类和对象详解(下)
|
7月前
|
存储 安全 算法
JavaSE&集合框架
JavaSE&集合框架
35 1
|
存储 容器
《JavaSE-第十七章》之LinkedList
《JavaSE-第十七章》之LinkedList
20507 34
|
存储 安全 Java
类和对象【JavaSE】
类和对象【JavaSE】
80 0
|
Java Android开发
【javaSE】 类和对象详解(上)
【javaSE】 类和对象详解(上)
|
存储 Java Android开发
【JAVASE】类与对象 上
【JAVASE】类与对象
|
存储 Java 编译器
【JavaSE】类和对象详解(2)
【JavaSE】类和对象详解(2)
|
存储 Java 编译器
【JavaSE】类和对象
本文讲解:类和对象的详解
下一篇
DataWorks