[19/03/24-星期日] 容器_Collection(集合、容器)之List(表,有顺序可重复)
一、 概念&方法
Collection 表示一组对象,它是集中、收集的意思。Collection接口的两个子接口是List、Set接口。
由于List、Set是Collection的子接口,意味着所有List、Set的实现类都有上面的方法。
如参见代码中test01和test02方法
【list接口】分为3种
List是有序、可重复的容器。List接口常用的实现类有3个:ArrayList(数组实现)、LinkedList(链表)和Vector(线程)。
有序:List中每个元素都有索引标记。可以根据元素的索引标记(在List中的位置)访问元素,从而精确控制这些元素。
可重复:List允许加入重复的元素。更确切地讲,List通常允许满足 e1.equals(e2) 的元素重复加入容器。
除了Collection接口中的方法,List多了一些跟顺序(索引)有关的方法,参见下表(测试代码test03):
1 /*
2 *测试list(接口) 需要用类去实现 如实现类ArrayList
3 * Collection接口的两个子接口是List、Set接口
4 */
5 package cn.sxt.collection;
6
7 import java.util.*;
8
9 public class Test_0324_List {
10 public static void main(String[] args) {
11 test03();
12
13
14 }
15 //测试Collection中单个容器的基本操作
16 public static void test01() {
17 Collection<String> c =new ArrayList<>();
18 System.out.println(c.size());//容器中元素的数量
19 System.out.println(c.isEmpty());//容器是否为空
20 c.add("Jack");//容器中增加元素
21 c.add("Tom");
22 System.out.println(c);//输出容器中的元素
23 System.out.println(c.contains("Tom"));//是不是包含Tom 是的话返回true
24
25 Object[] objs = c.toArray(); //把容器转成Object数组
26 System.out.println(Arrays.toString(objs));
27
28 c.remove("Jack");//把"Jack"的引用地址从对象c的容器中移除,并不是在内存中删除"Jack"
29 System.out.println(c);
30 c.clear();//清空所有元素
31 System.out.println(c.size());
32 }
33 //测试Collection中2个容器的操作
34 public static void test02() {
35 List<String> list01=new ArrayList<String>();//List可替换成Collection(因为前者是后者的子接口)
36 list01.add("a");
37 list01.add("b");
38 list01.add("c");
39
40 List<String> list02=new ArrayList<String>();
41 list02.add("a");
42 list02.add("e");
43 list02.add("f");
44
45 System.out.println("list01:"+list01);
46 System.out.println("list02:"+list02);
47
48 list01.addAll(list02);//最终元素落脚点在01容器中 取并集
49 System.out.println("把02的元素全部添加在01中(包括重复的):"+list01);
50 list01.removeAll(list02);//把01中 01和02都有的元素删掉(即a元素)
51 System.out.println("把01和02都有的元素删掉(即a元素):"+list01); //removeAll 移除共有的
52 list01.retainAll(list02);//取交集
53 System.out.println("把01和02都有的元素保留(其它删除):"+list01);//retainAll 保留共有的
54 System.out.println("01是否包含02中的所有元素:"+list01.contains(list02));//contains:包含的
55
56 }
57 //测试list接口中独有的方法 与索引相关
58 public static void test03() {
59 List<String> list=new ArrayList<String>();
60 list.add("A");
61 list.add("B");
62 list.add("C");
63 list.add("D");
64 System.out.println(list);
65
66 list.add(2, "小白");//在下标为2的位置插入一个新的元素,其它往后边移动
67 System.out.println(list);
68
69 list.remove(2);//把下标为2的位置的元素删除
70 System.out.println(list);
71
72 list.set(2, "菜鸟");//把下标为2的位置的元素替换掉
73 System.out.println(list);
74
75 System.out.println(list.get(2));//返回下标为2的处的元素
76
77 list.add("B");
78 System.out.println(list);
79
80 System.out.println(list.indexOf("B"));//返回元素"B"第一次出现时的下标
81 System.out.println(list.indexOf("F"));//返回元素"F"第一次出现时的下标,没有这个元素返回-1
82 System.out.println(list.lastIndexOf("B"));//返回元素"B"最后一次出现时的下标
83
84
85
86 }
89
90 }
ArrayList(数组):
1、底层是用数组实现的存储。 特点:查询效率高,增删效率低,线程不安全。ArrayList底层使用Object数组来存储元素数据。
所有的方法,都围绕这个核心的Object数组来开展。
2、 数组长度是有限的,而ArrayList是可以存放任意数量的对象,长度不受限制,那么它是怎么实现的呢?
本质上就是通过定义新的更大的数组,将旧数组中的内容拷贝到新数组,来实现扩容。ArrayList的Object数组初始化长度为10,
如果我们存储满了这个数组,需要存储第11个对象,就会定义新的长度更大的数组,并将原数组内容和新的元素一起加入到新数组中。
LinkedList(链表):
1、底层用双向链表实现的存储。特点:查询效率低,增删效率高,线程不安全。
双向链表也叫双链表,是链表的一种,它的每个数据节点中都有两个指针,分别指向前一个节点和后一个节点。
所以,从双向链表中的任意一个节点开始,都可以很方便地找到所有节点。
class Node {
Node previous; //前一个节点
Object element; //本节点保存的数据
Node next; //后一个节点
}
【代码示例】
/*
*测试链表 增删改查
*
*/
package cn.sxt.collection; public class Test_0324_LinkList<E> { //加了泛型的主类
private Node firstNode; //同一个包下的Node类 链表的第一个节点
private Node lastNode; // 链表的最后一个节点
private int size=0; public static void main(String[] args) { //主方法
Test_0324_LinkList<String> list=new Test_0324_LinkList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
System.out.println(list);//toString的好处是在碰到“println”之类的输出方法时会自动调用,不用写出来。
//System.out.println(list.get(1));//调用下边的get方法 给个索引位置返回具体元素
//list.remove(0);
list.insert(2, "我");
System.out.println(list);
} //添加一个新节点的方法
public void add(E e) {
Node node=new Node(e);//node 为新建的节点
if (firstNode==null) {//如果链表为空,新进来一个元素,则第一元素和最后一个元素都是它,因为链表中就一个元素
firstNode=node;
lastNode=node; } else { //如果不为空,新进来一个元素,新元素的前置节点就是原来的最后一个节点,同时把新元素的后置指针置为空
node.previous=lastNode;
node.next=null;
lastNode.next=node;//原来最后一个节点的后置节点就变成一个新节点了
lastNode=node; //新的节点就变成最后一个节点了
//每多加个字符,size加1 代表链表长度
}
size++;
} private void checkRange(int index) { //索引封装
if (index<0||index>size-1) {//判断索引位置是否合法
throw new RuntimeException("索引数字不合法:"+index);//抛出异常
} } //给个索引位置,返回具体元素的某项指标, 这里是这个元素的数值
public E get(int index) {
System.out.println(size); //做测试用 测试size的大小 checkRange(index);
Node temp=getNode(index);
return (temp!=null)? (E)temp.element:null;// (E)强制转型 如果temp不为空返回冒号前边的temp.element 否则返回null
} //通过索引返回一个具体元素
public Node getNode(int index){
checkRange(index);
Node tempNode=null;
//优化,当链表中数据比较多时用着快速
if (index<=(size>>1)) { //size>>1 右移1位相当于除以2
tempNode=firstNode;
for (int i=0; i<index; i++) {//通过for循环把索引所在的位置节点找出来,然后输出元素值
tempNode=tempNode.next; //如果小于中间值从前往后搜
}
}else {
tempNode=lastNode;
for (int i=index-1;i>index; i--) {//大于中间值,从后往前搜
tempNode=tempNode.previous;
}
}
return tempNode;
}
//在链表中插入一个元素
public void insert(int index,E e){ //alt+shift+R 替换字母
checkRange(index);
Node newNode=new Node(e);
Node tempNode=getNode(index);
if (tempNode!=null) {
Node up=tempNode.previous; up.next=newNode;
newNode.previous=up; newNode.next=tempNode;
tempNode.previous=newNode; }
/*if (index==0){ //在第一个位置增加元素的情况。 待完善!
firstNode=newNode.next;
lastNode=newNode.previous; lastNode.next=newNode;
newNode.previous=lastNode;
}
*/
size++; } //在链表中删除一个元素
public void remove(int index) {
checkRange(index);
Node tempNode=getNode(index);
if (tempNode!=null) {
Node up=tempNode.previous;
Node down=tempNode.next;
if (up!=null) {
up.next=down; //把这个元素后一个元素的地址直接放在这个元素前一个元素的next指针域
}
if (down!=null){
down.previous=up;// 把这个元素前一个元素的地址直接放在这个元素后一个元素的previous指针域
}
if (index==0){ //删除第1个元素的情况。 下一个元素是第一个元素
firstNode=down;
}
if (index==size-1){//删除最后1个元素的情况
lastNode=up;
}
}
size--; } //输出链表中的元素 toString的好处是在碰到“println”之类的输出方法时会自动调用,不用写出来。
public String toString () {
StringBuilder sb=new StringBuilder("[");//字符串 对象sb初始化 初始为字符串"[",然后依次追加 Node tempNode=firstNode; //初始临时节点为链表的第一个节点
while (tempNode!=null) {//如果元素不为空则输出元素的数据
sb.append(tempNode.element+","); //append 追加单个字符
tempNode=tempNode.next; //通过next找到下一个元素
}
sb.setCharAt(sb.length()-1,']'); //把sb对象的最后单个一个字符设置为"]"
return sb.toString();
} }
Vecto(矢量、向量)
Vector底层是用数组实现的List,相关的方法都加了同步检查,因此“线程安全,效率低”。 比如,indexOf方法就增加了synchronized同步标记。
区别:
如何选用ArrayList、LinkedList、Vector?
1. 需要线程安全时,用Vector。
2. 不存在线程安全问题时,并且查找较多用ArrayList(一般使用它)。
3. 不存在线程安全问题时,增加或删除元素较多用LinkedList。
[19/03/24-星期日] 容器_Collection(集合、容器)之List(表,有顺序可重复)的更多相关文章
- [19/03/25-星期一] 容器_Collection(集合、容器)之Set(集合、安置,无顺序不可重复)
一.概念&方法 Set接口继承自Collection,Set接口中没有新增方法,方法和Collection保持完全一致.. Set容器特点:无序.不可重复.无序指Set中的元素没有索引,只能遍 ...
- 编程体系结构(03):Java集合容器
本文源码:GitHub·点这里 || GitEE·点这里 一.集合容器简介 集合容器是Java开发中最基础API模块,通常用来存储运行时动态创建的元素,基本特点如下: 泛型特点,存储任意类型对象: 动 ...
- C++STL之set集合容器
set集合容器 set集合容器实现了红黑树(Red-Black Tree)的平衡二叉检索树的数据结构, 在 插入元素时, 它会自动调整二叉树的排列, 把该元素放到适当的位置, 以确保每个子树根节点的键 ...
- [19/03/27-星期三] 容器_Iterator(迭代器)之遍历容器元素(List/Set/Map)&Collections工具类
一.概念 迭代器为我们提供了统一的遍历容器的方式 /* *迭代器遍历 * */ package cn.sxt.collection; import java.security.KeyStore.Ent ...
- [19/03/23-星期六] 容器_ 泛型Generics
一.概念 生活中的容器不难理解,是用来容纳物体的,程序中的“容器”也有类似的功能,就是用来容纳和管理数据. 数组就是一种容器,可以在其中放置对象或基本类型数据. ---优势:是一种简单的线性序列,可以 ...
- stl之set集合容器应用基础
set集合容器使用一种称为红黑树(Red-Black Tree) 的平衡二叉检索树的数据结构,来组织泛化的元素数据.每一个节点包括一个取值红色或黑色的颜色域.以利于进行树的平衡处理.作为节点键值的元素 ...
- 【STL】 set集合容器常用用法
set集合容器:实现了红黑树的平衡二叉检索树的数据结构,插入元素时,它会自动调整二叉树的排列,把元素放到适当的位置,以保证每个子树根节点键值大于左子树所有节点的键值,小于右子树所有节点的键值:另外,还 ...
- Java集合容器简介
Java集合容器主要有以下几类: 1,内置容器:数组 2,list容器:Vetor,Stack,ArrayList,LinkedList, CopyOnWriteArrayList(1.5),Attr ...
- Java 容器(集合)
import java.util.*; 一.基础概念 1.什么是容器? 2.为什么需要容器? 3.容器的分类? 二.重点知识 List接口 Collections类 (1)为什么需要? Collect ...
随机推荐
- Centos 添加swap
swap是linux系统的虚拟内存,物理内存不足时,会用到.生产环境,最好添加上,以防内存异常暴增时,系统出现问题. 查看系统是否有swap分区,执行如下命令,若Swap那一行都为0,则表示没有Swa ...
- JS代码格式化排版工具,web文本编辑器
js格式化代码工具:http://www.cnblogs.com/blodfox777/archive/2008/10/09/1307462.html web文本编辑器 :http://www.div ...
- CSS像素、设备独立像素、设备像素之间关系
CSS像素.设备独立像素.设备像素,三者联系紧密又有很大的区别,而我们主要是在做移动端开发的时候需要更多地用到这些概念,那他们分别是指什么呢? 概念 CSS像素(CSS Pixel):适用于web编程 ...
- NBUT 1107——盒子游戏——————【博弈类】
盒子游戏 Time Limit:1000MS Memory Limit:65535KB 64bit IO Format: Submit Status Practice NBUT 110 ...
- Entity FrameWork利用Database.SqlQuery<T>执行存储过程并返回参数
目前,EF对存储过程的支持并不完善.存在以下问题: EF不支持存储过程返回多表联合查询的结果集. EF仅支持返回返回某个表的全部字段,以便转换成对应的实体.无法支持返回部分字段的情况. 虽然可以正常导 ...
- avalon实现日期联动
前言 上一篇我们说了下Avalon的一些概念,以及一些主要特性,至于Avalon的一些基础教程,正美老师已经做了非常全面的讲述,参见:http://www.cnblogs.com/rubylouvre ...
- tomcat和应用集成
将tomcat作为应用的一部分集成到应用中,使得应用可以直接开启http服务,对外提供接口.此时应用程序不必再遵守j2ee中的文件目录格式要求. 此种方式改变了以往先部署tomcat容器,再按照j2e ...
- 4、Angular2 pipe
1. stateless pipe 2.stateful pipe
- small zhishi
\\192.168.1.201\d$\Data 访问远程计算机文件资源管理器
- 选择排序——Java实现
一.排序思想 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理是: 从待排序列中选出最小(或最大)的一个元素,记录其下标(数组)的位置: 将记录的下标值与待排序列的第一个 ...