Java集合 ——List 接口
集合的数目是可变的,并且集合只能存储引用数据类型的数据,不能存放基本数据类型的数据,集合类和数组相比有很多不同之处,比如,数组的长度是不可变的,而集合的长度是可变的,而集合的长度是可变的;数组可以用来存储基本数据类型的数据,也可以存放引用类型的数据,而集合只能存放引用类型的数据,不能存放基本类型的数据。
说明:对以上框架图有几点说明;
1、所有的集合类都位于java.util包下。java的集合类主要由2个接口派生而出:Connection和Map。Connection和Map是java集合框架的根接口,这两个接口又包含了一些子接口或实现类。
2、集合接口,6个接口(短虚线表示),表示不同集合类型,是集合框架的基础。
3、抽象类,5个抽象类(长虚线表示),对集合接口的部分实现,可扩展为自定义集合类。
4、实现类,8个实现类(实线表示),对接口的具体实现。
5、Connection接口是一组允许重复的对象。
6、Set接口继承了Connection,集合元素不重复。
7、List接口继承了Connection,允许重复,维护元素插入顺序。
8、Map接口是键-值对象,与Connection对象没有什么关系。
9、Set/List/Map可以看做是集合的三大类:
List集合是有序集合,集合中的元素可以重复,访问集合中的元素可以根据索引进行访问。
Set集合是无序集合,集合中的元素不可重复,访问集合中的元素只能根据元素本身来访问。(也是集合元素不允许重复的原因)
Map集合中保存的key-value对形式的元素,访问时只能根据key值来访问其value。
List接口
List接口是一个有序集合,其元素以线性方式存储,集合中允许存放重复的元素。
List接口的定义如下:
public interface List<E> extends Collection<E> { }
相比于父接口Collection扩充的方法:
- get(int index) 返回此集合中指定元素的位置
- indexOf(Object o) 返回此集合中首次出现指定元素的索引,如果集合不包含此元素,返回-1
- lastindexOf(Object o) 返回此集合中首次出现指定元素的索引,如果集合不包含此元素,返回-1
- listIterator() 为ListIterator接口实例化,用于遍历集合中的元素
- listIterator(int index) 为ListIterator接口实例化,用于从集合指定位置遍历集合中的元素
- set(int index,E element) 替换指定位置元素
- subList(int fromIndex,int toIndex) 返回一个新的集合,包含当前集合fromIndex到 toIndex索引之间的元素
当应用场景中有很多的add/remove操作,只有少量的随机访问操作时,应该选择LinkedList;在其他的场景下,考虑使用ArrayList。
数组列表类:ArrayList
ArrayList类的定义如下:
public class ArrayList<E> extends AbstrctList<E> implements List<E>,RandomAccess,Cloneable,Serializable { }
ArrayList类实现List接口,可以直接通过ArrayList为List接口实例化。ArrayList类是数组列表类,实现了可变长度的数组,允许对集合中的元素进行快速的访问,但向ArrayList集合中插入和删除数据速度比较慢。
ArrayList集合中,插入一个元素时,列表需要将插入点后面的所有元素向后移动,而在删除一个元素时,需要将被删除元素的后面的所有元素向前移动,无论是插入还是删除,平均耗时为n/2
ArrayList集合允许所有的元素包括null.
每一个ArrayList实例都有一个默认的容量(10个),即存储元素的个数,这个容量可以随着元素的增加而自动变大(每次是原分配空间的1.5倍)。源码如下:
1.向集合添加元素
在Collection接口就已经定义了向集合添加元素的方法,add()和addAll()
package study;
import java.util.Collection;
import java.util.List;
import java.util.ArrayList;
public class Lianxi1 {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<String>(); //通过ArrayList实例化Collection
List<String> list = new ArrayList<String>(); //通过ArrayList实例化List
collection.add("1"); //添加元素
collection.add("2"); //添加元素
collection.add("3"); //添加元素
System.out.println("collection集合:"+collection); //打印集合中的元素
list.add("A"); //添加元素
list.add("C"); //添加元素
list.add(1,"B"); //向指定位置添加元素
list.addAll(0,collection); //向指定位置添加一个集合的所有元素
System.out.println("list集合:"+list); //打印集合中的元素
}
}
collection集合:[1, 2, 3]
list集合:[1, 2, 3, A, B, C]
add(E o)只是在集合的最后进行内容的追加,而add(int index,E element)可以在指定位置添加。
2.删除集合中的元素
ArrayList集合提供了专门用于删除元素的方法,Collection接口提供了remove()和removeAll()方法,在List接口中还提供了可以删除指定位置元素的方法remove(int index).
package study;
import java.util.Collection;
import java.util.List;
import java.util.ArrayList;
public class Lianxi1 {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<String>(); //通过ArrayList实例化Collection
List<String> list = new ArrayList<String>(); //通过ArrayList实例化List
collection.add("1"); //添加元素
collection.add("2"); //添加元素
collection.add("3"); //添加元素
System.out.println("collection集合:"+collection);
list.add("A"); //添加元素
list.add("C"); //添加元素
list.add(1,"B"); //向指定位置添加元素
list.addAll(0,collection); //向指定位置添加一个集合的所有元素
System.out.println("list集合删除前:"+list);
list.remove("B"); //删除元素B
list.remove(3); //删除指定位置的元素
list.removeAll(collection); //删除指定集合的元素
System.out.println("list集合删除后:"+list);
}
}
collection集合:[1, 2, 3]
list集合删除前:[1, 2, 3, A, B, C]
list集合删除后:[C]
3.集合的其他操作
package study;
import java.util.Collection;
import java.util.List;
import java.util.ArrayList;
public class Lianxi1 {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<String>(); //通过ArrayList实例化Collection
List<String> list = new ArrayList<String>(); //通过ArrayList实例化List
collection.add("1"); //添加元素
collection.add("2"); //添加元素
collection.add("3"); //添加元素
list.add("A"); //添加元素
list.add("C"); //添加元素
list.add(1,"B"); //向指定位置添加元素
list.addAll(0,collection); //向指定位置添加一个集合的所有元素
System.out.println("list集合:"+list);
List<String> subList=list.subList(1,5); //截取集合
System.out.println("subList集合:"+subList);
System.out.println("设置list集合元素前::"+list.get(3)); //获取指定位置的元素
list.set(3,"Set"); //设置指定位置的元素
System.out.println("设置list集合元素后::"+list.get(3)); //获取指定位置的元素
System.out.println("list集合中,元素3的位置:"+
list.indexOf("3")+",元素D的位置:"+list.indexOf("D")); //获取指定元素在集合中的索引位置,若不存在则返回-1
String arrString[] =list.toArray(new String[]{}); //将集合转为字符串数组
for (String str : arrString){ //输出数组元素
System.out.print(str+" ");
}
System.out.print("\nlist集合是否为空:"+list.isEmpty()); //判断集合是否为空
list.clear(); //清除集合中的所有元素
System.out.println("\nlist集合是否为空:"+list.isEmpty()); //判断集合是否为空
}
}
4.交集、并集和差集
package com.tulun.jihe;
import java.util.ArrayList;
/**
* @author lzq
*
*/
public class ArrayListDemo {
/**
* @param args
*
*/
public static void main(String[] args) {
ArrayList<Integer> arraylist = new ArrayList<Integer>();
arraylist.add(8);
arraylist.add(9);
ArrayList<Integer> arraylist2 = new ArrayList<Integer>();
arraylist2.add(9);
arraylist2.add(10);
ArrayList<Integer> arraylist3 = new ArrayList<Integer>();
//并集
for(int i = 0;i < arraylist.size();i++) {
arraylist3.add(arraylist.get(i));
}
for(int i = 0;i < arraylist2.size();i++) {
arraylist3.add(arraylist2.get(i));
}
for(int i:arraylist3) {
System.out.print(i+" ");
}
System.out.println();
//交集
for(int i = 0;i < arraylist.size();i++) {
if(arraylist2.contains(arraylist.get(i))) {
System.out.print(arraylist.get(i));
}
}
System.out.println();
//差集
arraylist.removeAll(arraylist2);
for(int i = 0;i < arraylist.size();i++) {
if(!arraylist2.contains(arraylist.get(i))) {
System.out.print(arraylist.get(i));
}
}
System.out.println();
for(int i = 0;i < arraylist.size();i++) {
if(!arraylist.contains(arraylist2.get(i))) {
System.out.print(arraylist2.get(i));
}
}
}
}
8 9 9 10
9
8
9
链表类:LinkedList类
LinkedList是链表类,采用链表结构保存元素。链表结构的优点是便于向集合插入和删除元素。因为在插入或删除元素时,不需要移动任何元素。但若需要随机访问集合中的元素时,LinkedList集合就显得比较慢了。
LinkedList类的定义如下:
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>,Queue<E>,Cloneable<E>,Serializable { }
LinkedList实现了List类,可以存在null元素,LinkedList类还提供了很多方法,这些方法可以使LinkedList类作为堆栈、队列或双向队列。
1.在链表的开头或结尾增加数据
可以通过LinkedList类的addFirst()和addLast()方法,将元素分别添加到链表的开头和结尾处
package study;
import java.util.List;
import java.util.LinkedList;
public class Lianxi1 {
public static void main(String[] args) {
LinkedList<String> link=new LinkedList<String>();
link.add("1"); //添加元素
link.add("2"); //添加元素
link.add("3"); //添加元素
System.out.println("添加前:"+link);
link.addFirst("F"); //添加元素在链表开头处
link.addLast("L"); //添加元素在链表结尾处
System.out.println("添加后:"+link);
}
}
添加前:[1, 2, 3]
添加后:[F, 1, 2, 3, L]
需要注意的是List接口中没有定义addFirst()和addLast()方法,所以不能使用:
List<String> link = new LinkedList<String>();
而是直接使用LinkedList类实现
2.区分获取表头的各个方法
在使用LinkedList类时,最常用的操作时获取表头,LinkedList类也提供了几个获取表头的方法,但他们的作用并不相同:
- getFirst():仅仅是获取表头
- element():获取但不移除此链表头
- peek():获取但不移除此链表头
- poll():获取并移除此链表头
- pop():获取并移除此链表头
package study;
import java.util.List;
import java.util.LinkedList;
public class Lianxi1 {
public static void main(String[] args) {
LinkedList<String> link=new LinkedList<String>();
link.add("1"); //添加元素
link.add("2"); //添加元素
link.add("3"); //添加元素
link.addFirst("F"); //添加元素在链表开头处
link.addLast("L"); //添加元素在链表结尾处
LinkedList<String> newLink=new LinkedList<String>(link);
System.out.println("添加元素后:\n\t"+link);
System.out.println("get()方法获取表头:"+link.getFirst());
System.out.println("使用get()方法后:\n\t"+link);
System.out.println("element()方法获取表头:"+link.element());
System.out.println("使用element()方法后:\n\t"+link);
System.out.println("peek()方法获取表头:"+link.peek());
System.out.println("使用peek()方法后:\n\t"+link);
System.out.println("poll()方法获取表头:"+link.poll());
System.out.println("使用poll()方法后:\n\t"+link);
System.out.println("pop()方法获取表头:"+link.pop());
System.out.println("使用pop()方法后:\n\t"+link);
System.out.println("****使用链表的先进先出*****");
int len=newLink.size();
for (int i=0;i<len;i++ ){
System.out.print(newLink.poll()+" ");
}
System.out.println();
}
}
添加元素后:
[F, 1, 2, 3, L]
get()方法获取表头:F
使用get()方法后:
[F, 1, 2, 3, L]
element()方法获取表头:F
使用element()方法后:
[F, 1, 2, 3, L]
peek()方法获取表头:F
使用peek()方法后:
[F, 1, 2, 3, L]
poll()方法获取表头:F
使用poll()方法后:
[1, 2, 3, L]
pop()方法获取表头:1
使用pop()方法后:
[2, 3, L]
****使用链表的先进先出*****
F 1 2 3 L
ArrayList和LinkedList的区别:
- ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
- 对随机访问(get()(查)和set()(改))来说,ArrayList优于LinkList,是因为LinkList要移动指针。
- 对于add()(增)和remove()(删),LinkedList相对于ArrayList是有优势的,因为后者需要移动数据
- ArrayList基于数组实现,而LinkedList是一个双向链表
十万个数据统计每个数据出现的次数:
/**
*
*/
package com.tulun.jihe;
import java.util.ArrayList;
import java.util.Random;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
/**
* 十万数据重复统计并打印
* 1.10万数据存储
* 2.数据统计
* @author 李正全
*
*/
public class A {
public static void main(String[] args) {
ArrayList<Integer> x = new ArrayList<Integer>(100000);
Random random = new Random();
for(int i = 0;i < 100000;i++) {
int val = random.nextInt(10);
x.add(val);
}
//对集合进行遍历
HashMap<Integer,Integer> y = new HashMap<Integer,Integer>();
Iterator<Integer> z = x.iterator();
while(z.hasNext()) {
Integer d = z.next();
if(!y.containsKey(d)) {
y.put(d, 0);
}
y.put(d,y.get(d)+1);
}
Iterator<Entry<Integer, Integer>> iterator = y.entrySet().iterator();
while(iterator.hasNext()) {
Entry<Integer, Integer> h = iterator.next();
Integer key = h.getKey();
Integer value = h.getValue();
System.out.println(key+":"+value);
}
}
}
0:9900
1:10157
2:10016
3:10126
4:10070
5:9924
6:9961
7:9815
8:10065
9:9966
上一篇: 55. 跳跃游戏
推荐阅读
-
Effective Java 第三版读书笔记——条款 22:接口应该只被用于定义类型
-
Java集合 ——List 接口
-
Effective Java 类和接口 第19条:接口只用于定义类型
-
Java泛型之泛型接口
-
Redis客户端Java服务接口封装 博客分类: DatabaseJava基础 javaredisspring
-
新浪实时股票数据接口http://hq.sinajs.cn/list=code 博客分类: 信息科技 新浪股票实时数据API接口
-
FastJson API接口消息返回JSON数据 博客分类: JAVA APIFastJson
-
免费天气预报接口 博客分类: java基础接口 天气预报接口免费天气预报接口
-
读WeakHashMap源码 博客分类: java集合 java
-
读WeakHashMap源码 博客分类: java集合 java