我是靠谱客的博主 冷艳飞机,最近开发中收集的这篇文章主要介绍List集合的常用实现类及虚类(含线程安全问题及List解决两个字符串互为字母异位词问题)一、相关介绍二、ArrayList实现类三、LinkedList实现类四:Vector实现类五、虚类(AbstractList)六、实例,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、相关介绍

        List是用的较多的集合类型,List是一个接口,具体使用List集合类型时,需要使用某个实现类。List接口的每个实现类也都实现了不同的数据结构,各自具有不同的特征。

  特点

        有序的,允许重复元素。顺序可以是自然排序或按对象加入到集合的顺序排序。因为List是有序的,所以它的对象可以被索引。ListIterator接口提供了迭代列表中元素的方法。抽象的List可以被随机的、通过数组、通过链接表或通过双向链接表进行访问。

  List接口中有以下几个常用实现类

        ArrayList:基于数组实现。每次增删都会形成新的数组,但数组有索引。优点:查询快;缺点:增加、删除慢、线程不安全。

        LinkedList:基于链表(双向)实现。每个元素存储本身内存地址的同时,还会存储下一个元素的地址。优点:增加、删除快;缺点:查询慢、线程不安全。

        Vector:基于数组实现。Vector和ArrayList用法上几乎相同,但Vector比较古老,一般不用。优点:线程安全;缺点:效率低。

二、ArrayList实现类

        ArrayList简述

        ArrayList是一个数组队列,相当于动态数组。线程不安全

        ArrayList继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能

        ArrayList实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在ArrayList中,我们即可以通过元素的序号快速获取元素对象,这就是快速随机访问。

        ArrayList实现了Cloneable接口,即覆盖了函数clone(),能被克隆。

        ArrayList实现java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。

        定义一个ArrayList的方式有如下几种

//默认创建一个ArrayList集合
List<String> list = new ArrayList<>();
//创建一个初始化长度为50的ArrayList集合
List<String> initlist = new ArrayList<>(50);
//将其他类型的集合转为ArrayList
List<String> setList = new ArrayList<>(new HashSet());

        ArrayList有很多常用方法,如add、addAll、set、get、remove、size、isEmpty等。

        ArrayList的遍历方式有如下几种

public class Test {
    public static void main(String[] args) throws Exception {
        ArrayList<String> list = new ArrayList<String>();
        list.add("A");
        list.add("B");
        list.add("C");
        list.add("D");
        list.add("E");
        list.add("F");
        //通过迭代器遍历
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()) {
            System.out.print(iterator.next());
        }
        System.out.println("n--------------------------");
        //for循环遍历
        for (String val : list) {
            System.out.print(val);
        }
        System.out.println("n--------------------------");
        //随机访问,通过list.get(i)获得索引值去遍历
        for(int i=0;i<list.size();i++) {
            System.out.print(list.get(i));
        }
    }
}

        ArrayList的去除重复数据的方式有如下几种

public class Test {
    public static void main(String[] args) throws Exception {
        ArrayList<String> list = new ArrayList<String>();
        list.add("A");
        list.add("B");
        list.add("C");
        list.add("D");
        list.add("E");
        list.add("B");
        System.out.println(Arrays.toString(removeDuplicate1(list).toArray()));
        System.out.println(Arrays.toString(removeDuplicate2(list).toArray()));
        System.out.println(Arrays.toString(removeDuplicate3(list).toArray()));
    }
    
    //1.循环list中所有的元素然后删除,有序
    public static ArrayList removeDuplicate1(ArrayList list){
        for(int i =0;i<list.size()-1;i++){
            for(int j=list.size()-1;j>i;j--){
                if(list.get(i).equals(list.get(j)))
                    list.remove(j);
            }
        }
        return list;        
    }
    
    //2.利用hashSet剔除重复元素,无序
    public static ArrayList removeDuplicate2(ArrayList list){
        HashSet set = new HashSet(list);
        //使用LinkedHashSet可以保证输入的顺序
        //LinkedHashSet<String> set2 = new LinkedHashSet<String>(list); 
        list.clear();        
        list.addAll(set);
        return list;        
    }
    
    //3.利用list的contains方法去重,无序
    public static ArrayList removeDuplicate3(ArrayList list){
        ArrayList tempList = new ArrayList(list.size());
        for(int i=0;i<list.size();i++){
            if(!tempList.contains(list.get(i)))
                tempList.add(list.get(i));
        }
        return tempList;        
    }
}

三、LinkedList实现类

        LinkedList简述

        LinkedList是一个双向列表,线程不安全

        LinkedList是一个继承于AbstractSequentialList的双向循环链表。它也可以被当作堆栈、队列或双端队列进行操作

        LinkedList实现List接口,能对它进行队列操作。

        LinkedList实现Deque接口,即能将LinkedList当作双端队列使用。

        LinkedList实现了Cloneable接口,即覆盖了函数clone(),能被克隆。

        LinkedList实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。

        定义一个LinkedList的方式有如下几种

//默认创建一个LinkedList集合
LinkedList<String> list = new LinkedList<>();
//将其他类型的集合转为LinkedList
LinkedList<String> setList = new LinkedList<>(new HashSet());

        LinkedList的常用方法以及遍历、去除重复数据方式和ArrayList一样。

四:Vector实现类

        Vector简述

        Vector是矢量队列,线程安全的

        Vector继承了AbstractList,实现了List。所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能

        Vector实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在Vector中,我们即可以通过元素的序号快速获取元素对象。这就是快速随机访问。

        Vector实现了Cloneable接口,即覆盖了函数clone(),能被克隆。

        定义一个Vector的方式有如下几种

//默认创建一个Vector集合
Vector<String> vector = new Vector<>();
//创建一个初始化长度为50的Vector集合,当由于增加数据导致容量增加时,每次容量会增加一倍。
Vector<String> initVector = new Vector<>(50);
//创建一个初始化长度为50的Vector集合,当由于增加数据导致容量增加时,每次容量会增加30。
Vector<String> initVector2 = new Vector<>(50,30);
//将其他类型的集合转为Vector
Vector<String> setVector = new Vector<>(new HashSet());

        Vector有很多常用方法,add、addAll、addElement、set、get、remove、removeElement、size、isEmpty等。Vector的遍历、去除重复数据方式和ArrayList一样。

五、虚类(AbstractList)

        AbstractList简述

        AbstractList 继承自 AbstractCollection抽象类,实现了List接口 ,是 ArrayList 和 AbstractSequentiaList 的父类。

        它实现了 List 的一些位置相关操作(比如 get,set,add,remove),是第一个实现随机访问方法的集合类,但不支持添加和替换。

        在 AbstractCollection 抽象类 中我们知道,AbstractCollection 要求子类必须实现两个方法: iterator() 和 size()。 AbstractList 实现了 iterator()方法:

public Iterator<E> iterator() {
    return new Itr();
}

        但没有实现 size() 方法,此外还提供了一个抽象方法 get():

public abstract E get(int location);
        因此子类必须要实现 get(), size() 方法。

        另外,如果子类想要能够修改元素,还需要重写 add(), set(), remove() 方法,否则会报 UnsupportedOperationException 错。

        AbstractList 作为 List 家族的中坚力量,既实现了 List 的期望,也继承了 AbstractCollection 的传统,还创建了内部的迭代器 Itr, ListItr,还有两个内部子类 SubList 和 RandomAccessSublist。如果需要深入了解AbstractList,建议去看相关源码。

六、实例

/**
 * 判断两个字符串中每个字符出现的次数是否都相同,若相同则说明两个字符串互为字母异位词
 * 输入: s = "anagram", t = "nagaram"
 * 输出: true
 */
public class Code1 {
    public static void main(String[] args) {
        System.out.println("结果为:"+compare1("gabtcadadefa","atagadabcdef"));
        System.out.println("结果为:"+compare2("abcadgtadefa","adaaabctdegf"));
        System.out.println("结果为:"+compare3("abcadgtadefa","adaaabctdegf"));
    }

    /**
     * 此方法先将两个字符串转换成数组,然后将其中一个数组存放到list集合中,再遍历另一个数组,
     * 如果list集合中包含数组元素,则将list集合中的该元素移除,最后判断list集合是否为空。
     * @param str1
     * @param str2
     * @return
     */
    public static boolean compare3(String str1,String str2){
        //将字符串转换成数组
        char [] c1 = str1.toCharArray();
        char [] c2 = str2.toCharArray();
        //借助List方法
        List<Character> list = new ArrayList<>();
        //将c1添加到list集合中
        for (int i = 0; i < c1.length; i++) {
            list.add(c1[i]);
        }
        //遍历c2
        for (int i = 0; i < c2.length; i++) {
            //判断c1的长度是否和c2相等,如果不相等直接返回false
            if(c1.length != c2.length){
                return false;
            }
            //遍历list,与c2中的元素进行比较,如果匹配到则将元素从列表中移除并跳出当前循环
            for (int j = 0; j < list.size(); j++) {
                if(list.get(j) == c2[i]){
                    list.remove(j);
                    break;
                }
            }
        }
        //判断list最后是否为空
        if (!list.isEmpty()){
            return false;
        }else {
            return true;
        }
    }

    /**
     * 此方法是通过定义一个数字先统计str1每个字母出现的次数,再遍历str2,遇到与str1相同的字母该字母次数减一
     * 最后判断每个字母的出现次数是否都为0。
     * @param str1
     * @param str2
     * @return
     */
    public static boolean compare1(String str1,String str2){
        //定义一个存放字母的数组
        int [] record = new int[26];
        //统计str1各个字母出现的次数
        for (char c : str1.toCharArray()){
            record[c - 'a'] += 1;
        }
        //str2中每出现一次与str1中相同的字母,该字母的次数减1
        for (char c : str2.toCharArray()){
            record[c - 'a'] -= 1;
        }
        //遍历数组record,查看每个字母的次数是否为0,如果是代表字符串互为字母异位词
        for (int i : record){
            if(i != 0){
                return false;
            }
        }
        return true;
    }

    /**
     * 此方法是通过先将str1和str2转换成数组,然后调用Arrays.sort()方法进行排序,
     * 最后判断两个数组是否相等。
     * @param str1
     * @param str2
     * @return
     */
    public static boolean compare2(String str1,String str2){
        //将字符串转换成数组
        char [] c1 = str1.toCharArray();
        char [] c2 = str2.toCharArray();
        //将数组进行排序
        Arrays.sort(c1);
        Arrays.sort(c2);
        //判断两个数组是否相等
        if(!Arrays.equals(c1,c2)){
            return false;
        }else {
            return true;
        }
    }
}

        如果你有其他理解或者我有哪里存在错误,欢迎一起在评论区 讨论。

最后

以上就是冷艳飞机为你收集整理的List集合的常用实现类及虚类(含线程安全问题及List解决两个字符串互为字母异位词问题)一、相关介绍二、ArrayList实现类三、LinkedList实现类四:Vector实现类五、虚类(AbstractList)六、实例的全部内容,希望文章能够帮你解决List集合的常用实现类及虚类(含线程安全问题及List解决两个字符串互为字母异位词问题)一、相关介绍二、ArrayList实现类三、LinkedList实现类四:Vector实现类五、虚类(AbstractList)六、实例所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部