当前位置: 首页 > 编程日记 > 正文

对比java_java集合对比

list与Set、Map区别及适用场景

1、List,Set都是继承自Collection接口,Map则不是

2、List特点:元素有放入顺序,元素可重复 ,Set特点:元素无放入顺序,元素不可重复,重复元素会覆盖掉,(注意:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的,加入Set 的Object必须定义equals()方法 ,另外list支持for循环,也就是通过下标来遍历,也可以用迭代器,但是set只能用迭代,因为他无序,无法用下标来取得想要的值。)

3.Set和List对比:

Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。

List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。

4.Map适合储存键值对的数据

5.线程安全集合类与非线程安全集合类

LinkedList、ArrayList、HashSet是非线程安全的,Vector是线程安全的;

HashMap是非线程安全的,HashTable是线程安全的;

StringBuilder是非线程安全的,StringBuffer是线程安全的。

下面是具体的使用介绍:

ArrayList与LinkedList的区别和适用场景

Arraylist:

优点:ArrayList是实现了基于动态数组的数据结构,因为地址连续,一旦数据存储好了,查询操作效率会比较高(在内存里是连着放的)。

缺点:因为地址连续, ArrayList要移动数据,所以插入和删除操作效率比较低。

LinkedList:

优点:LinkedList基于链表的数据结构,地址是任意的,所以在开辟内存空间的时候不需要等一个连续的地址,对于新增和删除操作add和remove,LinedList比较占优势。LinkedList 适用于要头尾操作或插入指定位置的场景

缺点:因为LinkedList要移动指针,所以查询操作性能比较低。

适用场景分析:

当需要对数据进行多次访问的情况下选用ArrayList,当需要对数据进行多次增加删除修改时采用LinkedList。

ArrayList,LinkedList,Vestor这三个类都实现了java.util.List接口,但它们有各自不同的特性,主要如下:

一、同步性

ArrayList,LinkedList是不同步的,而Vestor是同步的。所以如果不要求线程安全的话,可以使用ArrayList或LinkedList,可以节省为同步而耗费的开销。但在多线程的情况下,有时候就不得不使用Vector了。当然,也可以通过一些办法包装ArrayList,LinkedList,使他们也达到同步,但效率可能会有所降低。

二、数据增长

从内部实现机制来讲ArrayList和Vector都是使用Objec的数组形式来存储的。当你向这两种类型中增加元素的时候,如果元素的数目超出了内部数组目前的长度它们都需要扩展内部数组的长度,Vector缺省情况下自动增长原来一倍的数组长度,ArrayList是原来的50%,所以最后你获得的这个集合所占的空间总是比你实际需要的要大。所以如果你要在集合中保存大量的数据那么使用Vector有一些优势,因为你可以通过设置集合的初始化大小来避免不必要的资源开销。

三、检索、插入、删除对象的效率

ArrayList和Vector中,从指定的位置(用index)检索一个对象,或在集合的末尾插入、删除一个对象的时间是一样的,可表示为O(1)。但是,如果在集合的其他位置增加或移除元素那么花费的时间会呈线形增长:O(n-i),其中n代表集合中元素的个数,i代表元素增加或移除元素的索引位置。为什么会这样呢?以为在进行上述操作的时候集合中第i和第i个元素之后的所有元素都要执行(n-i)个对象的位移操作。

LinkedList中,在插入、删除集合中任何位置的元素所花费的时间都是一样的—O(1),但它在索引一个元素的时候比较慢,为O(i),其中i是索引的位置。

————————————————————————————————————————

一般大家都知道ArrayList和LinkedList的大致区别:

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。

2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。

3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

ArrayList和LinkedList是两个集合 类,用于存储一系列的对象引用(references)。例如我们可以用ArrayList来存储一系列的String或者Integer。那么 ArrayList和LinkedList在性能上有什么差别呢?什么时候应该用ArrayList什么时候又该用LinkedList呢?

一.时间复 杂度

首先一点关键的是,ArrayList的内部实现是基于基础的对象数组的,因此,它使用get方法访问列表中的任意一个元素时 (random access),它的速度要比LinkedList快。LinkedList中的get方法是按照顺序从列表的一端开始检查,直到另外一端。对 LinkedList而言,访问列表中的某个指定元素没有更快的方法了。

假设我们有一个很大的列表,它里面的元素已经排好序了,这个列表可能是ArrayList类型 的也可能是LinkedList类型的,现在我们对这个列表来进行二分查找(binary search),比较列表是ArrayList和LinkedList时的查询速度,看下面的程序:

Java代码

package com.mangocity.test;

import java.util.LinkedList;

import java.util.List;

import java.util.Random;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.Collections;

public class TestList ...{

public static final int N=50000;

public static List values;

static...{

Integer vals[]=new Integer[N];

Random r=new Random();

for(int i=0,currval=0;i

vals=new Integer(currval);

currval+=r.nextInt(100)+1;

}

values=Arrays.asList(vals);

}

static long timeList(List lst)...{

long start=System.currentTimeMillis();

for(int i=0;i

int index=Collections.binarySearch(lst, values.get(i));

if(index!=i)

System.out.println("***错误***");

}

return System.currentTimeMillis()-start;

}

public static void main(String args[])...{

System.out.println("ArrayList消耗时间:"+timeList(new ArrayList(values)));

System.out.println("LinkedList消耗时间:"+timeList(new LinkedList(values)));

}

}

我得到的输出 是:ArrayList消耗时间:15

LinkedList消耗时间:2596

这个结果不是固定的,但是基本上ArrayList的 时间要明显小于LinkedList的时间。因此在这种情况下不宜用LinkedList。二分查找法使用的随机访问(random access)策略,而LinkedList是不支持快速的随机访问的。对一个LinkedList做随机访问所消耗的时间与这个list的大小是成比例 的。而相应的,在ArrayList中进行随机访问所消耗的时间是固定的。

这是否表明ArrayList总是比LinkedList性能要好呢?这并不一定,在某些情况 下LinkedList的表现要优于ArrayList,有些算法在LinkedList中实现时效率更高。比方说,利用 Collections.reverse方法对列表进行反转时,其性能就要好些。

看这样一个例子,加入我们有一个列表,要对其进行大量的插入和删除操作,在这种情况下 LinkedList就是一个较好的选择。请看如下一个极端的例子,我们重复的在一个列表的开端插入一个元素:

Java代码

package com.mangocity.test;

import java.util.*;

public class ListDemo {

static final int N=50000;

static long timeList(List list){

long start=System.currentTimeMillis();

Object o = new Object();

for(int i=0;i

list.add(0, o);

return System.currentTimeMillis()-start;

}

public static void main(String[] args) {

System.out.println("ArrayList耗时:"+timeList(new ArrayList()));

System.out.println("LinkedList耗时:"+timeList(new LinkedList()));

}

}

这时我的输出结果是:ArrayList耗时:2463

LinkedList耗时:15

这和前面一个例子的结果截然相反,当一个元素被加到ArrayList的最开端时,所有已经存在的元素都会后 移,这就意味着数据移动和复制上的开销。相反的,将一个元素加到LinkedList的最开端只是简单的未这个元素分配一个记录,然后调整两个连接。在 LinkedList的开端增加一个元素的开销是固定的,而在ArrayList的开端增加一个元素的开销是与ArrayList的大小成比例的。

二.空间复 杂度

在LinkedList中有一个私有的内部类,定义如下:

Java代码

private static class Entry {

Object element;

Entry next;

Entry previous;

}

每个Entry对象 reference列表中的一个元素,同时还有在LinkedList中它的上一个元素和下一个元素。一个有1000个元素的LinkedList对象将 有1000个链接在一起的Entry对象,每个对象都对应于列表中的一个元素。这样的话,在一个LinkedList结构中将有一个很大的空间开销,因为 它要存储这1000个Entity对象的相关信息。

ArrayList使用一个内置的数组来存储元素,这个数组的起始容量是10.当数组需要增长时,新的容量按 如下公式获得:新容量=(旧容量*3)/2+1,也就是说每一次容量大概会增长50%。这就意味着,如果你有一个包含大量元素的ArrayList对象, 那么最终将有很大的空间会被浪费掉,这个浪费是由ArrayList的工作方式本身造成的。如果没有足够的空间来存放新的元素,数组将不得不被重新进行分 配以便能够增加新的元素。对数组进行重新分配,将会导致性能急剧下降。如果我们知道一个ArrayList将会有多少个元素,我们可以通过构造方法来指定 容量。我们还可以通过trimToSize方法在ArrayList分配完毕之后去掉浪费掉的空间。

三.总结

ArrayList和LinkedList在性能上各 有优缺点,都有各自所适用的地方,总的说来可以描述如下:

1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对 ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是 统一的,分配一个内部Entry对象。

2.在ArrayList的 中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。

3.LinkedList不 支持高效的随机元素访问。

4.ArrayList的空 间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间

可以这样说:当操作是在一列 数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在一列数据的前面或中 间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。

所以,如果只是查找特定位置的元素或只在集合的末端增加、移除元素,那么使用Vector或ArrayList都可以。如果是对其它指定位置的插入、删除操作,最好选择LinkedList

ArrayList与Vector的区别和适用场景

ArrayList有三个构造方法:

Java代码

public ArrayList(int initialCapacity)//构造一个具有指定初始容量的空列表。

public ArrayList()//构造一个初始容量为10的空列表。

public ArrayList(Collection extends E> c)//构造一个包含指定 collection 的元素的列表

Vector有四个构造方法:

Java代码

public Vector()//使用指定的初始容量和等于零的容量增量构造一个空向量。

public Vector(int initialCapacity)//构造一个空向量,使其内部数据数组的大小,其标准容量增量为零。

public Vector(Collection extends E> c)//构造一个包含指定 collection 中的元素的向量

public Vector(int initialCapacity,int capacityIncrement)//使用指定的初始容量和容量增量构造一个空的向量

ArrayList和Vector都是用数组实现的,主要有这么三个区别:

1.Vector是多线程安全的,线程安全就是说多线程访问同一代码,不会产生不确定的结果。而ArrayList不是,这个可以从源码中看出,Vector类中的方法很多有synchronized进行修饰,这样就导致了Vector在效率上无法与ArrayList相比;

2.两个都是采用的线性连续空间存储元素,但是当空间不足的时候,两个类的增加方式是不同。

3.Vector可以设置增长因子,而ArrayList不可以。

4.Vector是一种老的动态数组,是线程同步的,效率很低,一般不赞成使用。

适用场景分析:

1.Vector是线程同步的,所以它也是线程安全的,而ArrayList是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用ArrayList效率比较高。

2.如果集合中的元素的数目大于目前集合数组的长度时,在集合中使用数据量比较大的数据,用Vector有一定的优势。

HashSet与Treeset的适用场景

1.TreeSet 是二差树(红黑树的树据结构)实现的,Treeset中的数据是自动排好序的,不允许放入null值

2.HashSet 是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束

3.HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的String对象,hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例

适用场景分析:HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。为快速查找而设计的Set,我们通常都应该使用HashSet,在我们需要排序的功能时,我们才使用TreeSet。

HashMap与TreeMap、HashTable的区别及适用场景

HashMap 非线程安全

HashMap:基于哈希表实现。使用HashMap要求添加的键类明确定义了hashCode()和equals()[可以重写hashCode()和equals()],为了优化HashMap空间的使用,您可以调优初始容量和负载因子。

TreeMap:非线程安全基于红黑树实现。TreeMap没有调优选项,因为该树总处于平衡状态。

适用场景分析:

HashMap和HashTable:HashMap去掉了HashTable的contains方法,但是加上了containsValue()和containsKey()方法。HashTable同步的,而HashMap是非同步的,效率上比HashTable要高。HashMap允许空键值,而HashTable不允许。

HashMap:适用于Map中插入、删除和定位元素。

Treemap:适用于按自然顺序或自定义顺序遍历键(key)。

HashMap进行get操作就会产生死循环

http://www.cnblogs.com/kxdblog/p/4323892.html

相关文章:

.ARM.exidx

简介: .ARM.exidx is the section containing information for unwinding the stack. If your C program has functions that print out a stack backtrace, the functions will likely depend on this section being present. 相关的编译选项 -funwind-tables 二问…

Oracle VM VirtualBox安裝Windows 2000失败

问题:VirtualBox下安装Windows2000,设置网络后进入最后一步,复制组件……然后就是重启;再试还是重启!解决:在Oracle网站上查了一下资料:http://www.virtualbox.org/manual/ch12.html#idp1278616…

用户/目录操作

用户操作 useradd/adduser 创建用户 passwd 修改用户密码 userdel 删除用户 usermod 修改用户信息 -g<群组> 修改用户所属群组 -G<群组> 修改用户所属的附加群组 -l<帐户名> 修改账户名称 -u 修改用户ID -L锁定用户密码 -U 解除密码锁定 adduser -u用…

linux内核 -内存管理模块概图

1.从进程(task)的角度来看内存管理 每个进程对应一个task_struct;每个task_struct 里面包含指向mm_struct 的指针mm, mm_struct 里面的主要成员&#xff1a; a. 指向vma链表的头指针&#xff1a;mmap b. 指向vma红黑树的根节点: mm_rb c. 指向进程列表的指针pgb;vma(vm_are…

求一个字符串中连续出现的次数最多的子串

求一个字符串中连续出现的次数最多的子串。例如字符串“abababc”,最多连续出现的为ab&#xff0c;连续出现三次。要和求一个字符串中的最长重复子串区分开来&#xff0c;还是上面的字符串&#xff0c;那么最长的重复子串为abab。两个题目的解法有些类似&#xff0c;都用到了后…

java ftp 判断文件是否存在_FTP判断文件是否存在

FTP Client使用的是Apache Commons Net 3.3/*** 检查FTP上指定文件是否存在* param remoteFilePartNameList 文件路径* throws BusinessException* throws IOException*/private void checkFtpFileExist(List remoteFilePartNameList) throws BusinessException, IOException {…

软件定义光网络-SDON

为什么80%的码农都做不了架构师&#xff1f;>>> 软件定义光网络-SDON 随着宽带业务与应用的持续增长&#xff0c;光网络面临着新的发展机遇与技术挑战。作为当前业界研究热点之一&#xff0c;SDON聚焦于将软件定义技术融入光网络的综合解决方案&#xff0c;其关键技…

记录一次爬取某昵称网站的爬虫

同学跑去实习了...然后工作的时候要她用python写一个爬虫&#xff0c;爬取一万个可以用的用户昵称。&#xff08;为什么他们都能找到工作啊QAQ&#xff09; 然后&#xff0c;她找到了我...然后在我动笔的时候&#xff0c;发现之前写过的爬虫基本上忘完了...无奈下只好对着以前…

《LINUX3.0内核源代码分析》第一章:内存寻址

https://blog.csdn.net/ekenlinbing/article/details/7613334 摘要&#xff1a;本章主要介绍了LINUX3.0内存寻址方面的内容&#xff0c;重点对follow_page函数进行注释&#xff0c;以帮助读者大致了解ARM A9的页表组织。 读者需要理解一些基本概念&#xff1a;虚拟地址、物理地…

java integer int 比较_java Integer和int之间的比较问题是什么?

展开全部java Integer和int之间e68a84e8a2ad3231313335323631343130323136353331333365633864的比较问题。求解释public static void main(String[] args) { // TODO Auto-generated method stub Integer a new Integer(1); Integer b new Integer(1); int c1; Integer e 1;…

Oracle 12C -- 基于sequence的列的默认值

12C支持先创建一个sequence&#xff0c;然后再将该sequence指定为某个列的值的默认表达式。 和"identity column"具有以下不同点&#xff1a; 对列的个数没有限制 sequence必须在列定义之前定义 如果删除了sequence&#xff0c;会导致后面的insert报错 表的owner&…

Python的XML-RPC学习

编写客户端提交数据到服务器处理是程序员最常碰到的几个问题之一。各种不同的语言对此都有相应的解决方案。比如Unix下&#xff0c;C程序员们可以用SUNRPC&#xff0c;Java程序员则使用RMI来处理。大多数语言还都可以使用Web Service或者ICE。它们的使用方法类似&#xff0c;编…

Anaconda安装,jupyter notebook 使用说明

conda install pandas---安装pandas包 conda remove package_names conda update package_names conda list ---列出该环境下安装的package conda install nb_conda --------安装nb_conda用于notebook自动关联nb_conda的环境 conda create -n env_name package_name -------…

ARM32页表-虚拟地址到物理地址的转换

ARM32的页表 页表就是用于将虚拟地址转换为物理地址的转换关系表。访问虚拟地址时&#xff0c;计算机通过页表找到对应的实际物理地址访问。 我们在上一节介绍了内存管理模块概图, 怎么完成从pgd 到 page的转化呢&#xff1f; linux 内核code是通过follow_page来完成的…

java 重载 参数子类_java - Java中带有子类参数的函数重载 - 堆栈内存溢出

这个问题已经在这里有了答案&#xff1a;我有一个扩展了另一个类的类(在这种情况下&#xff0c;这是一个例外)&#xff1a;public class NewTypeException extends Exception {private String exceptionField;public String getExceptionField() {return exceptionField;}publi…

Caused by: java.sql.BatchUpdateException

Caused by: java.sql.BatchUpdateException: Table (%s) has been dropped, altered or renamed.解决方法重启项目转载于:https://www.cnblogs.com/mySummer/p/4723561.html

do{ ...}while(0)应用技巧

辅助定义复杂的宏example: #define A(args) do { a(args); b() } while(0);如果定义#define A(args) a(args);b();if(i > 0) A(i) if(i > 0 )do { a(2);b();} while(0) 或者while(1)a(args);b(); 这不是我们想要的&#xff0c;因为第二个b();不会被执行。代替g…

Idea--使用Idea调试设置

参考 https://blog.csdn.net/yyjava/article/details/81453748 关闭一些Idea默认设置&#xff0c;否则懵逼到爆炸.. 1.关闭集合类视图 2.关闭watch视窗默认调用toString&#xff08;真的很懵逼&#xff01;&#xff01;&#xff09; 转载于:https://www.cnblogs.com/microcat/p…

基于i2c子系统的驱动分析

https://blog.csdn.net/qq_28992301/article/details/52467766

creo JAVA_Creo 4.0二次开发工具框架搭建

一、新建MFC DLL工程二、配置项目属性附加依赖项中输入&#xff1a;netapi32.lib;psapi.lib;mpr.lib;wsock32.lib;protk_dll_NU.lib;protk_dllmd_NU.lib;protkmd_NU.lib;protoolkit_NU.lib;pt_asynchronous.lib;ptasyncmd.lib;ucore.lib;udata.lib;尝试编译工程&#xff0c;如果…

html5 FileReader初识

使用html5的FileReader可以实现多媒体文件的预览功能&#xff0c;代码如下&#xff1a; <html> <head> <script type"text/javascript"> var fileReader new FileReader(); fileReader.onload function(event) {document.getElementById(image).…

puppet aix之自动化用户管理

一、 用户组的管理 (一) Puppet组管理特性 1. manages_aix_lam用来管理AIX的LAM(Loadable Authentication Module)系统。 2. manages_members对于目录服务是组属性成员&#xff0c;而不是用户。 3. system_groups用来允许你创建比较小GID的系统组&#xff0c;一般小…

C# 文件操作

C# 文件操作文件操作: 检查 创建 读取 写入 修改 删除目录操作: 检查 创建 读取 写入 修改 删除文件操作 若要执行此操作...请参阅本主题中的示例...创建文本文件向文件写入文本写入文本文件向文件写入文本读取文本文件从文件读取文本向文件中追加文本File.AppendText FileInfo…

一种内存池管理技术

本文介绍一种内存池管理技术。 在m公司工作了4年多&#xff0c;一直负责内存池模块问题的处理&#xff0c;比如内存越界&#xff0c;data abort 系统异常的处理&#xff0c;本文加以总结&#xff0c;以便后续参考。 读本文之前&#xff0c;先有个约定&#xff0c;本文中提到的p…

企业支付宝账号开发接口实现

转载自&#xff1a;http://my.oschina.net/xshuai/blog/313809 关于即时到账的开发。审核通过。简单测试如下。 希望看的可以收藏或者赞一下哦。 1:拥有自己的支付宝企业账号。去产品商店选择适合自己的方案。并签约合同。 2:选择合适的商家收款产品并去签约。填写相应的信息 3…

Fastadmin管理Mysql_FastAdmin-CMS模版制作(6)-正式部署

一、工具信息介绍(1)服务器系统&#xff1a;CentOS7.2 64位系统&#xff1b;(2)服务器面板&#xff1a;宝塔&#xff0c;官网地址&#xff1a;https://www.bt.cn/&#xff1b;(3)PHP7.2&#xff1b;(4)mysql5.6&#xff1b;(5)Nginx&#xff1b;二、运行环境安装(1)进入宝塔官网…

使用微软提供的Office Online实现Office文档的在线查看,编辑等功能

使用微软提供的Office Online平台只需要一个网址即可在线查看Xls,doc,PPT等文档http://view.officeapps.live.com/op/view.aspx?src要查看的文档地址在线编辑需要登录live.com并从onedrive中打开或新建文档也可以来自在线模板(下面的Excel来自Excel Online模板&#xff0c;编辑…

HDU(1847)Good Luck in CET-4 Everybody!

利用PN分析求解此题。递推下去会发现3和3的倍数都是P点。 #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <set> using namespace std; int main() {int n;while(~scanf("%d",&n)){i…

uboot引导kernel - 1 - Flash的分区

uboot启动Linux内核过程分为4大步骤&#xff1a; 问题1&#xff1a;Flash的分区相关问题 在 上述步骤1/2/4 中都提到了从启动介质(iNand/SD)中读取uboot/kernel到SRAM/DDR中&#xff0c;那么具体从启动介质的什么位置分别读取呢&#xff1f;  上述步骤1中&#xff0c;iROM的…

fedora mysql默认密码忘记_Linux fedora 24 忘记密码图形化界面修改root密码的方法

方法及其简单&#xff0c;只需要两步即可&#xff1a;1、第一步&#xff1a;打开终端&#xff0c;输入sudo su命令。–此处的密码为普通用户的密码&#xff0c;也就是开机时输入的密码。2、第二步&#xff1a;直接sudo passwd root就重置了roor密码了。此时输入新的密码即可&am…