zoukankan      html  css  js  c++  java
  • Java 集合 -- List

    Java Collection 简介

    Java标准库自带的java.util包提供了集合类:Collection,它是除Map外所有其他集合类的根接口。

    Java的java.util包主要提供了以下三种类型的集合:

    • List:一种有序列表的集合,例如,按索引排列的Student的List;

    • Set:一种保证没有重复元素的集合,例如,所有无重复名称的Student的Set;

    • Map:一种通过键值(key-value)查找的映射表集合,例如,根据Student的name查找对应Student的Map。

    Java Collection 接口的继承关系如下图:

    Java集合的设计有几个特点:

    • 一是实现了接口和实现类相分离,例如,有序表的接口是List,具体的实现类有ArrayList,LinkedList等,

    • 二是支持泛型,我们可以限制在一个集合中只能放入同一种数据类型的元素,例如:

    List<String> list = new ArrayList<>(); // 只能放入String类型
    

    最后,Java访问集合总是通过统一的方式——迭代器(Iterator)来实现,它最明显的好处在于无需知道集合内部元素是按什么方式存储的。

    部分遗留的集合类(不建议使用):

    • Hashtable:一种线程安全的Map实现;

    • Vector:一种线程安全的List实现;

    • Stack:基于Vector实现的LIFO的栈。

    还有一小部分接口是遗留接口,也不应该继续使用

    • Enumeration:已被Iterator取代。

    使用 List

    在集合类中,List是最基础的一种集合:它是一种有序列表。List的索引和数组一样,从0开始。

    List 的实现类 ArrayList

    在实际应用中,需要增删元素的有序列表,我们使用最多的是ArrayList。实际上,ArrayList在内部使用了数组来存储所有元素。

    ArrayList把添加和删除的操作封装起来,让我们操作List类似于操作数组,却不用关心内部元素如何移动。

    List 的实现类 LinkedLsit

    LinkedList通过“链表”也实现了List接口。在LinkedList中,它的内部每个元素都指向下一个元素.

    比较一下ArrayList和LinkedList:

    通常情况下,我们总是优先使用ArrayList。

    List 的特点

    List接口允许我们添加重复的元素,即List内部的元素可以重复:

    public class ListMain {
        public static void main(String[] args){
            // 实例化一个 ArrayList 列表,命名为 list
            // 其中只能存放String 类型元素
            List<String> list = new ArrayList<>();
            list.add("apple"); // 使用 add()方法添加元素
            list.add("pear");
            list.add("apple");// 允许重复添加元素
            System.out.println(list.size()); // 使用size()方法获取列表长度
            System.out.println(list);
        }
    }
    

    List 允许添加 null

    public class ListMain {
        public static void main(String[] args){
            // 实例化一个 ArrayList 列表,命名为 list
            // 其中只能存放String 类型元素
            List<String> list = new ArrayList<>();
            list.add("apple"); // 使用 add()方法添加元素
            list.add(null);
            list.add("apple");// 允许重复添加元素
            String second = list.get(1); // 获取列表元素,下标从0开始
            System.out.println(second);
            System.out.println(list);
        }
    }
    

    创建 List

    除了使用ArrayList和LinkedList,我们还可以通过List接口提供的of()方法,根据给定元素快速创建List

    List<Integer> list = List.of(1, 2, 5);
    

    但是List.of()方法不接受null值,如果传入null,会抛出NullPointerException异常。

    注意:只有JDK9及以上,才支持 of()方法快速创建List,JDK8不支持。

    遍历 List

    可以用for循环根据索引配合get()方法遍历:

    public class ListMain {
        public static void main(String[] args){
            List<String> list = new ArrayList<>();
            list.add("apple");
            list.add("null");
            list.add("apple");
            for (int i=0; i<list.size(); i++){
                String s = list.get(i);
                System.out.println(s);
            }
        }
    }
    

    因为get(int)方法只有ArrayList的实现是高效的,换成LinkedList后,索引越大,访问速度越慢。

    所以要始终坚持使用迭代器Iterator来访问List

    Iterator本身也是一个对象,但它是由List的实例调用iterator()方法的时候创建的。

    Iterator<String> it = list.iterator()
    

    Iterator对象知道如何遍历一个List,并且不同的List类型,返回的Iterator对象实现也是不同的,但总是具有最高的访问效率。

    Iterator对象有两个方法:

    • boolean hasNext()判断是否有下一个元素,

    • next()返回下一个元素。

    因此,使用Iterator遍历List代码如下:

    public class ListMain {
     public static void main(String[] args){
            List<String> list = new ArrayList<>();
            list.add("apple");
            list.add("null");
            list.add("apple");
            Iterator<String> iterator = list.iterator();
            for (;iterator.hasNext();){
                String s = iterator.next();
                System.out.println(s);
            }
        }
    }
    

    记住,通过Iterator遍历List永远是最高效的方式。

    并且,由于Iterator遍历是如此常用,所以,Java的增强for循环本身就可以帮我们使用Iterator遍历。

    把上面的代码再改写如下:

    public class ListMain {
     public static void main(String[] args){
            List<String> list = new ArrayList<>();
            list.add("apple");
            list.add("null");
            list.add("apple");
            // Iterator<String> iterator = list.iterator();
            for (String s:list){ // 增强for循环
                // String s = iterator.next();
                System.out.println(s);
            }
        }
    }
    

    上述代码就是我们编写遍历List的常见代码。

    实际上,只要实现了Iterable接口的集合类都可以直接用增强for循环来遍历.

    Java编译器本身并不知道如何遍历集合对象,但它会自动把增强for循环变成Iterator的调用,原因就在于Iterable接口定义了一个Iterator iterator()方法,强迫集合类必须返回一个Iterator实例。

    List 与 Array 的转换

    array 表示数组。

    把List变为Array有三种方法,

    • 第一种是调用toArray()方法直接返回一个Object[]数组

    • 第二种方式是给toArray(T[])传入一个类型相同的Array,List内部自动把元素复制到传入的Array中

    • 最后一种更简洁的写法是通过List接口定义的T[] toArray(IntFunction<T[]> generator)方法

    每天学习一点点,每天进步一点点。

  • 相关阅读:
    root用户没有权限编辑其他用户处理
    php中 被遗忘的函数
    erlang file操作(IO编程)
    Linux下的MySQL自动备份脚本
    这就是传说中让理科生沉默,让文科生落泪的文理综合体(转)
    LINUX 忘记root密码
    php中 被遗忘的函数
    分页显示的常用操作方法
    php 接口类:interface
    php垃圾回收机制分析
  • 原文地址:https://www.cnblogs.com/youcoding/p/13418014.html
Copyright © 2011-2022 走看看