集合——List集合
集合类出现的原因
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
集合中存储的是对象所在堆内存中的地址值,数组也是如此。
数组和集合类的区别
数组虽然也可以存储对象,但长度是固定的;
集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。
集合类的特点
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
集合框架的构成及分类
为什么会出现这么多的容器呢?
因为每个容器对数据的存储方式不同,这个存储方式称之为:数据结构
Collection定义了集合框架的共性功能。
1,添加
boolean add(e);添加对象
boolean addAll(collection);添加传入的集合中的所有元素
2,删除
boolean remove(e);删除对象
boolean removeAll(collection);删除传入集合中的所有元素
void clear();清空集合
3,判断
boolean contains(e);判断是否包含该对象
boolean isEmpty();判断该集合是否为空
4,获取
Iterator iterator();迭代器:集合中取出元素的方式
int size();获取该集合中元素的个数
5,获取交集
boolean retainAll();
6,集合变数组
Object[] toArray();
代码示例:
/**
Collection方法演示
*/
import java.util.*;
class CollectionDemo
{public static void main(String[] args) {//用Collection子类ArrayList创建集合容器ArrayList al1 = new ArrayList();ArrayList al2 = new ArrayList();//添加元素al2.add("java01");al2.add("java02");al1.add("java01");al1.add("java02");al1.add("java03");al1.add("java04");//删除元素al1.remove("java03");sop(al1);al1.removeAll(al2);sop(al1);//判断集合sop(al1.isEmpty());sop(al1.contains(al2));//获取sop(al1.size());Iterator it = al1.iterator();while (it.hasNext()){sop(it.next());}//取交集sop(al1.retainAll(al2));//集合变数组Object[] obj = al2.toArray();for (int a = 0;a<al2.size() ;a++ ){sop(obj[a]);}}public static void sop(Object obj){System.out.println(obj);}
}
迭代器Iterator的说明
JAVA中有多种容器,因为每种容器的数据结构不同,所以取出对象的动作细节也不同,他们各自都有自己的取出方式,这些取出方式被定义在集合的内部,所以这个取出方式可以直接访问集合内部的元素。这些取出方式都有共性的内容,判断和取出,被定义在集合中的内部类都符合一个规则,该规则就是Iterator,内部类对外提供了一个公共的方法iterator();
举例说明:
电玩城里面抓娃娃的机器,装娃娃的箱子相当于是一个容器,里面的娃娃就是一个个对象,箱子里面抓娃娃的夹子就是迭代器,他被封装在容器的内部,外面的操纵杆是对外暴露的方法
Iterator的两种方式
/**
Iterator的两种定义方式
*/
import java.util.*;
class IteratorDemo
{public static void main(String[] args) {ArrayList al = new ArrayList();al.add("java01");al.add("java02");get1(al);get2(al);}//方式一: while循环public static void get1(ArrayList al){Iterator it = al.iterator();while (it.hasNext()){sop(it.next());}}//方式二:for循环,使用这种结构,节省内存public static void get2(ArrayList al){for (Iterator it = al.iterator();it.hasNext() ; ){sop(it.next());}}public static void sop(Object obj){System.out.println(obj);}
}
Collection集合体系
Collection
|--List:元素是有序的,元素可以重复。因为该集合体系有索引。
|--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。
|--LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢。线程不同步。
|--Vector:底层是数组数据结构。线程同步。被ArrayList替代了。因为效率低。
数组结构和链表数据结构说明
数组数据结构
查询块,是因为该数据结构中每个元素都有指定的角标记录,只要知道这角标就可以查到该元素;
增删慢,是因为每加入一个元素,其后面的元素都要向后面移动位置
图示:
链表数据结构
增删块,是因为该数据结构中每个元素都记住它前面的一个元素。删除元素时,数据结构中其实是这样的操作,断开这个元素指向的前一个元素,再断开它后面指向它的元素,最后将它后面的元素指向它前面的元素即可;
查询慢,是因为该数据结构中的元素只知道它前面的元素,除非你找到与之关联的元素,否则就要一直找下去
图示:
List特有的方法:凡是可以操作角标的方法都是该体系特有的方法
增 add();addAll(index,collection);
删 remove(index);
改 set(index,element);
查 get(index);subList(from,to);int indexOf(obj);ListIterator();
ListIterator()说明:
List集合特有的迭代器。ListIterator是Iterator的子接口。在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。所以,在迭代时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作,如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。该接口只能通过List集合的listIterator方法获取。
ListIterator接口的特有方法
Boolean hasPrevious():
逆向遍历元素,和hasNext()方法相反
int nextIndex()
返回对 next 的后续调用所返回元素的索引。
E previous()
返回列表中的前一个元素。
int previousIndex()
返回对 previous 的后续调用所返回元素的索引。
void remove()
从列表中移除由 next 或 previous 返回的最后一个元素(可选操作)。
void set(E e)
用指定元素替换 next 或 previous 返回的最后一个元素(可选操作)。
代码示例:
/**
List集合的特有方法演示
*/
import java.util.*;
class ListDemo
{public static void main(String[] args) {ArrayList al = new ArrayList();//添加元素al.add("java01");al.add("java02");al.add("java03");al.add("java04");al.add("java05");print(al);//删除元素al.remove(2);sop(al);//修改元素al.set(2,"java02");sop(al);get(al);}//获取元素//方式一public static void print(ArrayList al){for (int a = 0;a<al.size() ;a++ ){sop("al"+a+"="+al.get(a));}}//方式二public static void get(ArrayList al){ListIterator li = al.listIterator();//list集合特有的迭代器while (li.hasNext()){sop(li.next());}}public static void sop(Object obj){System.out.println(obj);}
}
枚举
枚举是vector特有的取出方式;
其中的Enumeration和Iterator用法一致;
Vector和ArrayList的区别也就在此,Vector支持枚举。
代码示例:
/** Enumeration演示 */ import java.util.*; class EnumerationDemo {public static void main(String[] args) {Vector v = new Vector();v.add("java01");v.add("java02");v.add("java03");v.add("java04");v.add("java05");enumeration(v);}public static void enumeration(Vector v){for (Enumeration en = v.elements();en.hasMoreElements() ; ){System.out.println(en.nextElement());}} }
LinkedList的特有方法
addFirst();在所有元素的最前面添加元素
addLast();在所有元素的最后面添加元素
getFirst();获取第一个位置的元素
getLast();获取最后一个位置的元素
获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException
removeFirst();获取第一个元素,并删除掉此元素
removeLast();获取最后一个元素,并删除掉此元素
获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchElementException
在JDK1.6出现了替代方法。
以后使用这些方法
offerFirst();在集合的开头插入元素
offerLast();在集合的最后插入元素
peekFirst();
peekLast();
获取元素,但不删除元素。如果集合中没有元素,会返回null。
pollFirst();
pollLast();
获取元素,但是元素被删除。如果集合中没有元素,会返回null。
代码示例:
/**
LinkedList特有方法演示
*/
import java.util.*;
class LinkedListDemo
{public static void main(String[] args) {LinkedList link = new LinkedList();link.addFirst("java01");link.addFirst("java02");link.addFirst("java03");link.addFirst("java04");sop(link);link.addLast("java01");link.addLast("java02");link.addLast("java03");link.addLast("java04");sop(link);sop(link.getFirst());sop(link.getLast());sop(link.removeFirst());sop(link.removeLast());}public static void sop(Object obj){System.out.println(obj);}
}
JDK1.6版本
/**
LinkedListJDK1.6 特有方法演示
*/
import java.util.*;
class LinkedListDemo
{public static void main(String[] args) {LinkedList link = new LinkedList();link.offerFirst("java01");link.offerFirst("java02");link.offerFirst("java03");link.offerFirst("java04");sop(link);link.offerLast("java01");link.offerLast("java02");link.offerLast("java03");link.offerLast("java04");sop(link);sop(link.peekFirst());sop(link.peekLast());sop(link.pollFirst());sop(link.pollLast());}public static void sop(Object obj){System.out.println(obj);}
}
练习总结:
练习一
使用LinkedList模拟一个堆栈或者队列数据结构。
/**
使用LinkedList模拟一个堆栈或者队列数据结构。堆栈:先进后出 如同一个杯子。
队列:先进先出 First in First out FIFO 如同一个水管。
*/
import java.util.*;
/*
此类将linkedList方法封装进我们自己创建的对象中;
实际开发中这种用法非常多见
*/
class DuiLie
{private LinkedList link;DuiLie(){link = new LinkedList();}public void myAdd(Object obj){link.addFirst(obj);}/*将此处的removeLast改成removeFirst方法,就是先进后出的,堆栈数据结构*/public Object myGet(){return link.removeLast();}public boolean isNull(){return link.isEmpty();}
}
class DuiLieTest
{public static void main(String[] args) {DuiLie dl = new DuiLie();dl.myAdd("java01");dl.myAdd("java02");dl.myAdd("java03");dl.myAdd("java04");while (!(dl.isNull())){System.out.println(dl.myGet());}}
}
总结:
练习一可以直接使用LinkedList集合完成,但实际开发中,这种方法并不适用。实际开发中,都是将其封装起来,定义我们自己的名称,对外暴露自己设定的方法,增强通用性。
这一思想非常重要
练习二:
删除集合中的重复元素
/**
需求:删除ArrayList集合中的重复元素
分析:
1,建立一个临时容器,先放入一个元素
2,放入之后每放入一个元素就和其中的元素记性比较,如果相同则不存入,否则存入
3,输出该集合
步骤:
1,临时容器al,放入元素al.add();
2,遍历容器中的数组:Iterator(),判断元素是否存在:contains(),不同存入add()
3,sop(al)
*/
import java.util.*;
class RemoveRepeatTest
{public static void main(String[] args) {ArrayList al = new ArrayList();al.add("java01");al.add("java02");al.add("java01");al.add("java02");al.add("java01");sop(al);//输出al集合中的元素al = removeRepeat(al);//删除集合al中的重复元素sop(al);//输出取出重复元素后的集合}public static ArrayList removeRepeat(ArrayList al){ArrayList newAl = new ArrayList();//建立临时容器,用于存储未重复的元素/*遍历集合al中的元素,将元素存入临时容器newAl中,判断临时容器中是否有该元素,如果没有就存入。注意:一个hasNext()只能对应一个next();*/for (Iterator it = al.iterator();it.hasNext() ; ){Object obj = it.next();//一个hasNext()只能对应一个next(),所以设置一个引用类型变量进行存储if (!(newAl.contains(obj)))//判断这个集合中是否包含这个元素{newAl.add(obj);}}return newAl;}public static void sop(Object obj){System.out.println(obj);}
}
练习三:
将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
/**
将自定义对象作为元素存到ArrayList集合中,并去除重复元素。比如:存人对象。同姓名同年龄,视为同一个人。为重复元素。
思路:
1,存储元素
2,删除重复元素
3,输出元素
步骤:
1.定义Person类,该类中具有getName方法和getAge方法,复写equals方法
2.定义一个临时容器,用于存储未重复的元素,判断临时容器中是否包含该元素,不包含则存储,否则不存储
3,输出临时容器
*/
import java.util.*;
class MyTest
{public static void main(String[] args) {ArrayList al = new ArrayList();/*这里有一个自动向上转型的过程,Person对象向上转型为object对象因为add()方法中添加的是object对象,这里存入person对象,相当于Object obj = new Person("zhangsan01",11);父类引用指向子类对象,多态的表现*/al.add(new Person("zhangsan01",11));al.add(new Person("lisi01",22));al.add(new Person("zhangsan02",22));al.add(new Person("lisi01",22));al.add(new Person("zhangsan03",43));al = removeRepeat(al);iterator(al);}//遍历集合中的对象,public static void iterator(ArrayList al){for (Iterator it = al.iterator();it.hasNext() ; ){/*it.next()中取出的是Object对象,要对person进行操作,需要将Object对象强制转换成Person对象*/Person p = (Person)it.next();sop(p.getName()+"::"+p.getAge());}}//判断临时容器中是否存在相同的元素,不同的存储 ,相同的不进行存储public static ArrayList removeRepeat(ArrayList al){ArrayList newAl = new ArrayList();for (Iterator it = al.iterator();it.hasNext(); ){Object obj = it.next();/*注意:contains()方法底层调用的方法是equals()方法在执行contains方法时,默认调用equals方法*/if (!(newAl.contains(obj))){newAl.add(obj);}}return newAl;}public static void sop(Object obj){System.out.println(obj);}
}
class Person
{private String name;private int age;Person(String name,int age){this.name = name;this.age = age;}/*Object中的equals比较的是对象的地址值,这里覆写对象的equals方法,使其具备判断对象的姓名和年龄是否相同的功能*/public boolean equals(Object obj){//不包含就不进行判断if (!(obj instanceof Person)){return false;}Person p = (Person)obj;//Object对象强转成Person对象return this.name.equals(p.name) && this.age == p.age;}public String getName()//该方法主要用于迭代集合中对象的内容时,被调用{return name;}public int getAge(){return age;}
}
程序知识点总结:
1,存储元素和存储对象是两个不同的概念
对元素进行操作的过程相对较简单
对对象进行操作的过程中需要对对象进行强制转换,因为集合中涉及到的方法,传入的都是Object对象(例如add(Object obj)),所以,如果要对子类对象进行操作,需要将该对象进行强制向下转型;
2,contains()方法和remove()方法底层调用的都是equals()方法,这点非常重要;
这也是remove方法的返回值类型是Boolean型的原因
集合——List集合相关推荐
- 由浅入深理解java集合(二)——集合 Set
2019独角兽企业重金招聘Python工程师标准>>> 一.HashSet类 HashSet是Set接口的典型实现,实现了Set接口中的所有方法,并没有添加额外的方法,大多数时候使用 ...
- 【Groovy】map 集合 ( map 集合操作符重载 | 使用 << 操作符添加一个元素 | 代码示例 )
文章目录 一.使用 " << " 操作符添加一个元素 二.代码示例 一.使用 " << " 操作符添加一个元素 对 map 集合 使用 ...
- 【Groovy】map 集合 ( map 集合操作符重载 | *. 展开操作符 | 代码示例 )
文章目录 一.map 集合 " *. " 展开操作符 二.代码示例 一.map 集合 " *. " 展开操作符 对 map 集合使用 " *. &qu ...
- 【Groovy】map 集合 ( map 集合操作符重载 | - 操作符重载 | 代码示例 )
文章目录 一.map 集合 " - " 操作符重载 二.完整代码示例 一.map 集合 " - " 操作符重载 对 map 集合 使用 " - &qu ...
- 【Groovy】map 集合 ( map 集合操作符重载 | + 操作符重载 | 代码示例 )
文章目录 一.map 集合 " + " 操作符重载 二.代码示例 一.map 集合 " + " 操作符重载 对 map 集合使用 " + " ...
- 【Groovy】map 集合 ( map 集合遍历 | 使用 map 集合的 each 方法遍历 map 集合 | 代码示例 )
文章目录 一.使用 map 集合的 each 方法遍历 map 集合 二.代码示例 一.使用 map 集合的 each 方法遍历 map 集合 遍历 map 集合 , 可以调用 map 集合的 eac ...
- 【Groovy】集合遍历 ( 集合中有集合元素时调用 flatten 函数拉平集合元素 | 代码示例 )
文章目录 一.集合中有集合元素时调用 flatten 函数拉平集合元素 二.完整代码示例 一.集合中有集合元素时调用 flatten 函数拉平集合元素 在上一篇博客 [Groovy]集合遍历 ( 操作 ...
- 【Groovy】集合遍历 ( 使用 for 循环遍历集合 | 使用集合的 each 方法遍历集合 | 集合的 each 方法返回值分析 )
文章目录 一.使用 for 循环遍历集合 二.使用 each 方法遍历集合 三.集合的 each 方法返回值分析 四.完整代码示例 一.使用 for 循环遍历集合 使用 for 循环 , 遍历集合 , ...
- set集合判断集合中是否有无元素_集合 (Set) | 一山不容二虎的 Python 数据类型
点击上方"可乐python说"关注公众号,点击右上角 "..."选择"设为星标"第一时间获取最新分享! 前言 Hi,大家好,我是可乐, 今天 ...
- 离散数学反对称关系_【离散数学】1.2&1.3集合与元素,集合与集合之间的关系...
离散数学是编程人员进阶的必修科目,是计算机专业学生的基础课程之一,多为理论性知识,较抽象. [离散数学]第一章(集合论基础)的小节主要有: 1.1集合的定义和表示 1.2集合与元素的关系 1.3集合与 ...
最新文章
- Java服务提供_JAVA 服务提供者框架介绍
- heritrix 3.2.0 -- 环境搭建
- 实体银行网点一定被消灭?银行如何平衡数字创新与线下体验?
- 使用C++实现多张BMP图片转换为YUV动画----附加淡入淡出转场(逐渐变明变暗),及垂直滑像转场(逐行渐变)
- 为什么java容器能在for each中遍历(Map除外)
- [导入]ADO.NET Entity Framework 深入分析, Part 6 – 处理并发(Concurrency Handling)
- sqlalchemy与mysql区别_sqlite3和sqlalchemy有什么区别?
- c语言编程计算人口增长模式转变示意图,读“人口增长模式及其转变示意图”,回答下列问题。(5分)(1)图中字母代表的人口增长模式是:A____________、B____...
- range作用于对象global失败_彻底弄懂JavaScript作用域问题
- android 验证码图片识别_图片验证码的识别技术
- 实习成长之路:MySQL十:怎么给字符串字段加索引?
- Re0:DP学习之路 01背包如何打印路径?
- Linux缺少libaio包
- 系统重启-------即java代码重启tomcat!
- ImportError: Couldn‘t import Django. Are you sure it‘s installed and available on your PYTHONPATH en
- 某程序员求助:简历造假,如今面试通过,要坦白吗?
- 【绝知此事要躬行】线性表之链表OJ(下)
- Windows Sqlserver Automatic Log Audit Via C/C++
- Cortex-M MMU内存管理单元和 Linux
- Required field ‘serverProtocolVersion‘ is unset! User: root is not allowed to impersonate root