概述
一、相关介绍
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)六、实例所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复