Java集合之List介绍

List

List集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引。

注意:
List集合默认按元素的添加顺序设置元素索引,例如第一次添加元素索引为0,第二次添加索引为1…

List是Collection的子接口,可以使用Collection接口里的全部方法。因为List是有序集合,所以它有一些根据索引来操作集合元素的方法。

方法如下:

  • void add(int index,Object element)
    将元素element 添加到List集合index处。
  • boolean addAll(int index ,Collection c)
    将集合c所包含的所有元素插入到List集合的index处。
  • Object get(int index )
    返回集合index索引处的元素。
  • int indexOf(Object o)
    返回对象o在List集合中第一次出现的位置索引。
  • int lastIndexOf(Object o)
    返回对象o在List集合中最后一次出现的位置索引。
  • Object remove(int index)
    删除并返回index索引出的元素。
  • Object set(int index ,Object element)
    将index索引处的元素替换成element对象,返回被替换的旧元素。
  • List subList(int fromIndex,int toIndex)
    返回从索引fromIndex(包含)到索引toIndex(不包含)处所有集合元素组成的子集合。
    1.8
  • void replaceAll(UnaryOperator operator)
    根据operator)指定的计算规则重新设置List集合的所有元素。
  • void sort(Comparator c)
    根据Comparator参数对List集合的元素排序。

示例:

package com.list;

import java.util.ArrayList;

/**
 * 
 * @author hhmsw
 *
 */
public class ListTest {

    public static void main(String[] args) {

        ArrayList list = new ArrayList();
        list.add("java疯狂讲义");
        list.add("java多线程");
        list.add("java真经");
        System.out.println(list);//[java疯狂讲义, java多线程, java真经]
        list.add(1, "C++");
        System.out.println(list);//[java疯狂讲义, C++, java多线程, java真经]
        list.remove(0);
        System.out.println(list);//[C++, java多线程, java真经]
        System.out.println(list.subList(1, 2));//[java多线程]
        list.set(1, new String("C#"));
        System.out.println(list);//[C++, C#, java真经]
        System.out.println(list.indexOf(new String("C")));
    }
}

List判断两个对象是否相等只要通过equals方法比较返回true即可

示例:

class A{
    @Override
    public boolean equals(Object obj) {
        return true;
    }
}

    public static void main(String[] args) {
    ArrayList list2 = new ArrayList();
        list2.add("java疯狂讲义2");
        list2.add("java多线程2");
        list2.add("java真经2");

        list2.remove(new A());
        System.out.println(list2);//[java多线程2, java真经2]
        list2.remove(new A());
        System.out.println(list2);//[java真经2]

原因:

以上程序试图删除一个A对象,List将会调用该A对象的equals方法依次与集合元素进行比较,如果该equals()方法以某个集合元素作为参数时返回true,List将会删除该元素。A类重写了equals()方法,该方法总是返回true。
所以每次从List集合删除A对象时,总是删除List集合中的第一个元素。

固定长度的List

操作数组的工具类,Arrays,该工具类里提供了asList(Object…a)方法,该方法可以把一个数组或者指定个数的对象转换成一个List集合。

注意:
这个List集合既不是ArrayList实现类的实例,也不是Vector实现类的实例,而是Arrays的内部类ArrayList的实例,Arrays.ArrayList是一个固定长度的List集合,程序只能遍历访问该集合里的元素,不可增加、删除该集合里的元素。
如果试图通过这两个方法来增加、删除Arrays$ArrayList集合里的元素,将会引发异常UnsupportedOperationException

示例:

public static void main(String[] args) {
    List fixedList = Arrays.asList("Java原则","C++","Html5");
        System.out.println(fixedList);//[Java原则, C++, Heml5]
        System.out.println(fixedList.getClass());//class java.util.Arrays$ArrayList
        //抛出异常:java.lang.UnsupportedOperationException
        fixedList.add("C#");
        fixedList.remove("Java原则");
}

迭代器ListIterator

List提供了Listiterator()方法,该方法返回一个ListIterator对象,ListIterator接口集成了Iterator接口并且增加了专门操作List的方法。

  • boolean hasPrevious()
    返回该迭代器关联的集合是否还有上一个元素。
  • Object previous()
    返回该迭代器的上一个元素。
  • void add(Object o)
    在指定位置添加一个元素。

示例:

package com.list;

import java.util.ArrayList;
import java.util.ListIterator;

/**
 *  
 * @author hhmsw
 *
 */
public class ListIteratorTest {

    public static void main(String[] args) {
        String [] books = new String[]{"Java基础","Java精要","Js实战"};
        ArrayList list = new ArrayList();
        for (String book : books) {
            list.add(book);
        }

        ListIterator itera = list.listIterator();
        while(itera.hasNext()){
            System.out.println(itera.next());
            //Java基础,Java精要,Js实战
        }

        while (itera.hasPrevious()) {
            System.out.println(itera.previous());
            //Js实战,Java精要,Java基础
        }
    }
}

ArrayList 和 Vector

相同点:

  • 两者都是List接口的实现类,支持List接口的全部功能。
  • 两者内部都封装了一个动态的、允许在分配的Object[]数组,默认长度10,当添加元素超出该数组长度时,initialCapacity值会自动增加。

区别:

  • ArrayList是线程不安全的,必须手动保证该集合的同步性;
  • Vector是线程安全的,无须程序保证该集合的同步性,因此Vector性能要比ArrayList性能低;
  • Vector是一个古老的集合(从JDK1.0就有了)因此,即便要保证集合元素的同步性,也尽量不要使用Vector。

注意:
如果集合中需要添加大量的元素,可使用ensureCapacity(int minCapacity)方法一次性的增加initialCapacity。从而减少内存重分配的次数,提高性能。

重新分配Object[]长度的方法:

  • ensureCapacity(int minCapacity)
    将ArrayList或Vector集合的Object[]数组长度增加大于或等于minCapacity值。
  • void trimToSize()
    调整ArrayList或Vector集合的Object[]数组的长度为当前元素的个数。调用该方法可以减少ArrayList或Vector集合对象占地用的存储空间。

LinkedList

LinkedList类是List接口的实现类,它可以根据索引来随机访问集合中的元素。除此之外,LinkedList还实现了Deque接口,可以被当成双端队列来使用,因此既可以被当成“棧”来使用,也可以当成队列使用。

LinkedList集合用法,示例:

package com.list;

import java.util.LinkedList;

public class LinkedListTest {

    public static void main(String[] args) {

        LinkedList list = new LinkedList();
        list.add("Java");
        //讲一个字符串的元素加入棧的顶部
        list.push("java讲义");
        //将字符串元素加入队列的尾部
        list.offer("Java疯狂讲义");
        //将一字符串的元素添加到队列的头部(相当于棧的顶部)
        list.offerFirst("C++");

        //输出:[C++, java讲义, Java, Java疯狂讲义]
        System.out.println(list);

        //访问并不删除棧顶元素,输出:C++
        System.out.println(list.peekFirst());
        //访问并不删除队列最后一个元素,输出:Java疯狂讲义
        System.out.println(list.peekLast());
        //将棧顶元素弹出,输出:C++
        System.out.println(list.pop());
        //访问并删除队列的最后一个元素,输出:Java疯狂讲义
        System.out.println(list.pollLast());

        System.out.println(list);
        //[java讲义, Java]
    }
}

上面程序分别示范了LinkedList作为List集合、双端队列、棧的用法。LinkedList是一个功能非常强大的集合类。

LinkedList与ArrayList、ArrayDeque的实现机制完全不同,ArrayList、ArrayDeque内部以数组的形式来保存集合中的元素,因此随机访问集合元素时有较好的性能;

而LinkedList内部是以链表的性质来保存集合中的元素,因此随机访问集合元素时性能较差,但在插入、删除元素时性能比较出色(只需改变指针所指的地址即可)

需要指出的是,Vector也是以数组的形式来存储集合元素的,但因为它实现了线程的同步功能(而且实现机制也不好),所以各方面都比较差。

一般来说,由于数组以一块连续内存去来保证所有数组元素,所以数组在随机访问时性能最好,所有的内部以数组作为底层实现的集合,在随机访问时性能都比较好;而内部以链表作为底层实现的集合在执行插入、删除操作时有较好的性能

但总体来说,ArrayList的性能笔LinkedList的性能要好,因此大部分时候应该使用它ArrayList。

建议:

  • 如果遍历List集合元素,对于ArrayList、Vector集合,应该使用随机访问的方法(get)来遍历集合元素,这样性能更好;
  • 对于LinkedList集合,则应该使用迭代器Iterator来遍历集合元素。
  • 如果要经常执行插入、删除操作来改变包含大量数据的List集合的大小,可考虑使用Linkedlist集合。

原因:使用ArrayList、Vector集合可能需要经常重新分配内部数组的大小,效果可能较差。

如果有多个线程需要同事访问List集合中的元素,那么可以考虑使用Collections将集合包装成线程安全的集合。

Friends are lost by calling often and calling seldom.
交往过密过疏,都会失去朋友。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值