集合类——Collection、List、Set接口
集合类
Java类集
我们知道数组最大的缺陷就是:长度固定。从jdk1.2开始为了解决数组长度固定的问题,就提供了动态对象数组实现框架——Java类集框架。Java集合类框架其实就是Java针对于数据结构的一种实现。
Java类集的本质就是动态对象数组。
在Java类集中提供有两个最为核心的接口:Collection和Map接口。
1、Collection接口
(1)定义:
public interface Collection<E> extends Iterable<E>
Collection是单个集合保存的最大接口。
Collection与写过的链表类似,每一次进行数据操作的时候只能对单个对象进行处理。且从jdk1.5开始追加泛型应用,这样可以避免ClassCastException异常的出现,里面的所有保存数据类型应该相同。
(2)常用方法
|
向集合中添加元素:boolean add(E e) 向集合中添加一组元素:boolean addAll(Collection<? extends E> c) 清空集合数据: void clear() 查找数据是否存在:boolean contains(Object o) 删除数据:boolean remove(Object o) 取得集合长度:int size() 将结合变为对象数组:Object[] toArray() 取得Iterator接口对象,用于集合输出:Iterator<E> iterator() |
实则Collection接口只是一个存储数据的标准,并不能用来区分存储类型。如:需要区分可存储数据的重复与否。所以我们一般用来使用的是Collection的两个子接口:List和Set。
2、List接口
public interface List<E> extends Collection<E>
新增方法:
|
根据索引取得保存数据: E get(int index) 修改数据: E set(int index, E element) |
List接口与Collection接口相比,比其增加了一个get()、set()方法,可以通过指定的索引值取得修改、内容。要想取得接口的实例化对象则其必须有子类,在List接口下有三个常用子类:ArrayList、Vector、LinkedList.
(1)ArrayList
public class ArrayList<E> extends AbstractList<E>
ArrayList是针对于List的数组实现。
-
package mycollection;
-
-
-
-
import java.util.*;
-
-
-
-
public class Test {
-
-
public static void main(String[] args) {
-
-
//这时候集合中只能存String类型的数据
-
-
List<String> list = new ArrayList<>();
-
-
list.add("hello");
-
-
list.add("world");
-
-
//添加重复元素
-
-
list.add("hello");
-
-
list.add("陕科大");
-
-
System.out.println(list);
-
-
//返回集合中元素的个数
-
-
System.out.println("新增元素后集合长度:"+list.size());
-
-
//判断集合是否为空
-
-
System.out.println("集合是否为空:"+list.isEmpty());
-
-
//判断集合是否包含指定元素(元素存在)
-
-
System.out.println("集合中是否包含元素“hello”:"+list.contains("hello"));
-
-
//判断集合是否包含指定元素(元素不存在)
-
-
System.out.println("集合中是否包含元素“haha”:"+list.contains("haha"));
-
-
//取得集合指定位置的元素
-
-
System.out.println("下标为2的元素:"+list.get(2));
-
-
//修改指定位置的元素
-
-
System.out.println("修改下标为3的元素:");
-
-
list.set(3, "lemon");
-
-
System.out.println("修改元素后将集合中元素转化为数组并打印"+list.toArray());
-
-
for (String string : list) {
-
-
System.out.print(" "+string);
-
-
}
-
-
System.out.println();
-
-
//清空集合中元素
-
-
System.out.println("清空集合:");
-
-
list.clear();
-
-
System.out.println("清空后集合是否为空:"+list.isEmpty());
-
-
}
-
-
}
由上述运行结果我们可以发现List可以存储重复元素。
get()方法是List子接口提供的,根据指定下标返回元素。若我们要对Collection接口实现此操作,则引用该将其转换为对象数组再进行操作。
-
//利用Collection实现get()方法
-
-
public class Test {
-
-
public static void main(String[] args) {
-
-
//这时候集合中只能存String类型的数据
-
-
Collection<String> list = new ArrayList<>();
-
-
list.add("hello");
-
-
list.add("world");
-
-
//添加重复元素
-
-
list.add("hello");
-
-
list.add("陕科大");
-
-
//操作以Object为主,可能需要向下转型,就会出现ClassCastException异常
-
-
Object[] object = list.toArray();
-
-
System.out.println(Arrays.toString(object));
-
-
System.out.println("下标为2的元素:"+object[2]);
-
-
}
-
-
}
(1)Vector
Vector是jdk1.0提出的,而ArrayList是jdk1.2提出的,Vector相对使用较少。
Vector的使用与ArrayList的使用类似
-
public class Test {
-
-
public static void main(String[] args) {
-
-
//这时候集合中只能存String类型的数据
-
-
List<String> list = new Vector<>();
-
-
list.add("hello");
-
-
list.add("world");
-
-
//添加重复元素
-
-
list.add("hello");
-
-
System.out.println(list);
-
-
//返回集合中元素的个数
-
-
System.out.println("新增元素后集合长度:"+list.size());
-
-
//判断集合是否为空
-
-
System.out.println("集合是否为空:"+list.isEmpty());
-
-
//判断集合是否包含指定元素(元素存在)
-
-
System.out.println("集合中是否包含元素“hello”:"+list.contains("hello"));
-
-
//判断集合是否包含指定元素(元素不存在)
-
-
System.out.println("集合中是否包含元素“haha”:"+list.contains("haha"));
-
-
//取得集合指定位置的元素
-
-
System.out.println("下标为2的元素:"+list.get(2));
-
-
//修改指定位置的元素
-
-
System.out.println("修改下标为3的元素:");
-
-
list.set(1, "lemon");
-
-
System.out.println("修改元素后将集合中元素转化为数组并打印"+list.toArray());
-
-
for (String string : list) {
-
-
System.out.print(" "+string);
-
-
}
-
-
System.out.println();
-
-
//清空集合中元素
-
-
System.out.println("清空集合:");
-
-
list.clear();
-
-
System.out.println("清空后集合是否为空:"+list.isEmpty());
-
-
}
-
-
}
ArrayList和Vector的区别:
A. 时间上:Vector是jdk1.0提供的;而ArrayList是jdk1.5提供的。
B. 处理形式:Vector是同步处理,性能较低;而ArrayList是异步处理,性能相对高。
C. 数据安全:Vector是线程安全的;而ArrayList是非线程安全的。
D. 输出形式:Vector支持Iterator、ListIterator、 foreach、Enumeration输出;而ArrayList支持Iterator、ListIterator、foreach输出。
(2)LinkedList
若还是利用子类向父类转型来使用的话,LinkedList的使用和前面两者也没什么区别。
ArrayList和LinkedList的区别:
观察ArrayList的源码,可以发现ArrayList里面存放的是一个数组,如果实例化此对象时传入了数组的大小,则里面保存的数组就会开辟一个定长的数组,但是后续中再进行数据保存,若该长度不够使用则会对数组进行动态扩充。所以我们在使用ArrayList时最好对其设置初始化大小。
LinkedList就是一个纯粹的链表实现,除性能高外与我们编写的链表没有什么区别。
ArrayList封装的是数组,而LinkedList封装的是链表。进行查找时ArrayList的时间复杂度为1,而LinkedList的时间复杂度为n。
3、Set接口
与List接口相比Set:Set中的内容是不允许重复的,且没有对Collection接口再进行方法的扩充。所以Set中没有get()方法。
Set接口中提供与两个常用子类:HashSet(无需存储)和TreeSet(有序存储)。
-
public class Test{
-
public static void main(String[] args) {
-
//Set<Integer> set = new HashSet<>();
-
Set<Integer> set = new TreeSet<>();
-
set.add(20);
-
set.add(6);
-
set.add(15);
-
set.add(-3);
-
set.add(20);
-
//添加重复元素
-
System.out.println(set);
-
}
-
}
HashSet运行后结果 TreeSet运行后结果
由此我们可以看出HashSet是对集合进行无需存储,而TreeSet则对集合进行有序存储(采用升序模式进行排列)。
(1)TreeSet中排序的分析
因此我们对TreeSet的排序来进行分析:
由于TreeSet可以进行排序操作,所以我们可以来实现数据的排序处理。此时进行的排序实际是针对对象数组进行的排序处理,而如果要对对象数组进行排序,则对象所在的类要实现Comparable接口并且要覆写compareTo()方法(要利用Comparable接口进行大小关系比较时必须要对所有的属性进行比较操作)。
-
//自定义类
-
class Person implements Comparable<Person>{
-
private String name;
-
private Integer age;
-
@Override
-
public String toString() {
-
return "Person [name=" + name + ", age=" + age + "]";
-
}
-
Person(String name, Integer age) {
-
super();
-
this.name = name;
-
this.age = age;
-
}
-
public String getName() {
-
return name;
-
}
-
public void setName(String name) {
-
this.name = name;
-
}
-
public Integer getAge() {
-
return age;
-
}
-
public void setAge(Integer age) {
-
this.age = age;
-
}
-
@Override
-
public int compareTo(Person o) {
-
if(this.age > o.age) {
-
return 1;
-
}else if(this.age < o.age) {
-
return -1;
-
}else {
-
return this.name.compareTo(o.name);
-
}
-
}
-
}
-
public class Test{
-
public static void main(String[] args) {
-
Set<Person> set = new TreeSet<>();
-
set.add(new Person("lemon",20));
-
set.add(new Person("demon", 20));
-
set.add(new Person("lemon",20));
-
System.out.println(set);
-
}
-
}
这样一个一个属性进行比较的操作过于麻烦,所以一般情况下我们都使用HashSet。
(2)重复元素的判断在使用TreeSet子类进行数据保存时。重复元素的判断依靠Comparable接口来实现。但是这并不是全部Set接口判断元素重复的方式,因为如果使用的是HashSet子类,因为其和Comparable没有任何关系,所以它判断重复要依靠Object类的两个方法:
hash码: public native int hashCode();
对象比较:public boolean equals(Object obj);
在Java中进行对象比较的操作有两个步骤:第一步要通过一个对象的唯一编码找到一个对象的信息,当编码匹配之后再进行下一步操作利用equals()方法进行内容比较。
-
/*
-
* 标识对象的唯一性
-
* */
-
//自定义类
-
class Person implements Comparable<Person>{
-
private String name;
-
private Integer age;
-
@Override
-
public String toString() {
-
return "Person [name=" + name + ", age=" + age + "]";
-
}
-
Person(String name, Integer age) {
-
super();
-
this.name = name;
-
this.age = age;
-
}
-
public String getName() {
-
return name;
-
}
-
public void setName(String name) {
-
this.name = name;
-
}
-
public Integer getAge() {
-
return age;
-
}
-
public void setAge(Integer age) {
-
this.age = age;
-
}
-
-
public int compareTo(Person o) {
-
if(this.age > o.age) {
-
return 1;
-
}else if(this.age < o.age) {
-
return -1;
-
}else {
-
return this.name.compareTo(o.name);
-
}
-
}
-
@Override
-
public int hashCode() {
-
return Objects.hash(name,age);
-
}
-
@Override
-
public boolean equals(Object obj) {
-
if(this == obj) {
-
return true;
-
}
-
if(obj == null|| getClass()!=obj.getClass()) {
-
return false;
-
}
-
Person person = (Person) obj;
-
return Objects.equals(name,person.name)
-
&& Objects.equals(age,person.age);
-
}
-
-
}
-
public class Test{
-
public static void main(String[] args) {
-
Set<Person> set = new HashSet<>();
-
set.add(new Person("lemon",20));
-
set.add(new Person("lemon",20));
-
set.add(new Person("demon", 18));
-
System.out.println(set);
-
}
-
}
不覆写hashCode()和equals()方法或只覆写一个运行结果:
两个方法覆写后运行结果:
所以想要标识出对象的唯一性,则必须覆写hashCode()和equals()两个方法。
如果两个对象的hashCode()相同,equals()不同;或两个对象的equals()相同,而hashCode()不同时,这两个对象都是不能消除。而只有当两个对象的hashCode()和equals()都相同时,这两个对象才能判定为同一对象,即相同。
所以在保存自定义类信息时,建议使用List接口。而保存系统类信息时,建议使用Set接口。
集合类——Collection、List、Set接口的更多相关文章
- Java中的集合(五)继承Collection的List接口
Java中的集合(五)继承Collection的List接口 一.List接口简介 List是有序的Collection的,此接口能够精确的控制每个元素插入的位置.用户能够根据索引(元素在List接口 ...
- ios 对象的集合类(collection classes)
当你着手为你的应用编写代码的时候,你会发现有许多可供使用的Objective-C的框架类,其中尤其重要的就是基础框架类,它为平台所有的应用提供基础服务.基础框架类中包括了表示字符串和数字等基本数据类型 ...
- Java容器深入浅出之Collection与Iterator接口
Java中用于保存对象的容器,除了数组,就是Collection和Map接口下的容器实现类了,包括用于迭代容器中对象的Iterator接口,构成了Java数据结构主体的集合体系.其中包括: 1. Co ...
- Java中的集合(六)继承Collection的Set接口
Java中的集合(六)继承Collection的Set接口 一.Set接口的简介 Set接口和List接口都是继承自Collection接口,它与Collection接口中功能基本一致,并没有对Col ...
- Java中的集合(三)继承Collection的Queue接口
Java中的集合(三)继承Collection的Queue接口 一.Queue介绍 Queue接口继承自Collection接口,是Java中定义的一种队列数据结构,元素是有序的(按插入顺序排序),先 ...
- 集合类 collection接口 ArrayList
数组: 存储同一种数据类型的集合容器.数组的特点:1. 只能存储同一种数据类型的数据.2. 一旦初始化,长度固定. 3. 数组中的元素与元素之间的内存地址是连续的. : Object类型的数组可以存储 ...
- 集合类 collection接口 Set
Collection接口的另外一种实现为Set集合,主要有两种实现方式一种为HashSet另一种为TreeSet,两种实现都依赖与对应的Map实现类. 代码如下: public HashSet() { ...
- 集合类(Collection和Map接口)简介
集合分为Collection和Map,详细分类如下图所示: 以下是测试验证代码: //HashSet,无序(存取不一致).去重 Set set_H = new HashSet(); set_H.add ...
- 集合类 collection接口 LinkedList
LinkedList 是另外一种重要的数据结构形式, 底层是使用了双向链表数据结构, 特点: 查询速度慢,增删快. 继承关系如下: 可以发现,LinkedList同时实现了Quene和Deque接口. ...
随机推荐
- git与pycharm的使用详解(git+gitlab+pycham)
前言 当自动化框架搭建出来后,需要多个人来使用框架,写自动化用例. 在这个阶段,我们不可能将写好的代码打包发给其他人,这样很麻烦,多人协作一点也不灵活. 这时候,就提现出了git的价值 一.下载安装 ...
- zabbix部署文档
环境:zabbix server centos 7 1611最小化安装 172.16.103.2 zabbix client Centos 7 1611 最小化安装 172.16.103.3 1,配置 ...
- ABAP——系统状态&用户状态修改、查询
前言:在ABAP开发中有时候会涉及到状态的变更,比如销售订单的系统状态变更未审批->已审批.设备的在运->报废等,在这里就需要用到标准函数I_CHANGE_STATUS.STATUS_CH ...
- Go语言核心36讲(Go语言实战与应用一)--学习笔记
23 | 测试的基本规则和流程 (上) 在接下来的日子里,我将带你去学习在 Go 语言编程进阶的道路上,必须掌握的附加知识,比如:Go 程序测试.程序监测,以及 Go 语言标准库中各种常用代码包的正确 ...
- NOIP模拟92&93(多校26&27)
前言 由于太菜了,多校26 只改出来了 T1 ,于是直接并在一起写啦~~~. T0 NOIP 2018 解题思路 第一次考场上面写三分,然而我并不知道三分无法处理不是严格单峰的情况,但凡有一个平台都不 ...
- CentOS7 hadoop3.3.1安装(单机分布式、伪分布式、分布式)
@ 目录 前言 预先设置 修改主机名 关闭防火墙 创建hadoop用户 SSH安装免密登陆 单机免密登陆--linux配置ssh免密登录 linux环境配置Java变量 配置Java环境变量 安装Ha ...
- 《Python语言程序设计》【第3周】基本数据类型
实例3:天天向上的力量 #DayDayUpQ1.py dayup = pow(1.001,365) daydown = pow(0.999,365) print("向上: {:.2f},向下 ...
- vue + cesium开发(3) cesium1.87更新问题
官方在2021年11月1号更新日志中记录了他们把zip.js升级到了2.3.12以适应webpack4中的关于import.meta不兼容的语法问题,但是经过实测,1.87版本依然没有解决这个问题,所 ...
- [loj6500]操作
差分,令$b_{i}=a_{i-1}\oplus a_{i}$,对于一个区间$[l,r]$,相当于令$a_{l-1}=a_{r+1}=0$之后求出$b_{l..r+1}$,对区间$[i-k,i)$异或 ...
- [luogu3706]硬币游戏
(可以参考洛谷4548,推导过程较为省略) 定义$g_{i}$表示随机$i$次后未出现给定字符串的概率,$f_{k,i}$表示随机$i$次后恰好出现$s_{k}$(指第$k$个字符串)的概率,设两者的 ...