JAVA集合类兄妹List和Set
List 接口及其实现类
- 有序集合,集合中每个元素都有其对应的顺序索引,类似数组,索引也是从 0 开始,可以根据元素的索引,来访问元素。
- List 集合允许添加相同的元素,因为它是通过下标来取值的,不会因为元素相同而产生冲突。
如何应用接口List的一个重要实现类 ArrayList呢?
- ArrayList集合类的定义与添加集合元素(不同类型的元素)
2.访问集合元素通过get(集合下标) 获取的是抽象Object对象类型,这里需要强转弱,自动拆箱
- String s1=(String)ls.get(0);
- int s2=(Integer)ls.get(1);
- double s1=(Double)ls.get(2);
3.删除元素
ls.remove(1);//删除下标为1的对象
4.遍历集合元素
数组遍历是通过游标遍历,List集合类遍历集合元素类似于数组遍历,也可以通过索引遍历,另外List集合类还可以使用Iterator接口遍历集合元素(实际上,所有Collection集合类都可以使用Iterator接口遍历集合元素,因为实现类都实现Iterable<E>接口
- 使用Iterator接口遍历集合元素
5.对元素集合进行排序
一般有两种方式
第一种是
封装类实现了Comparator接口,封装类就是平常的VO/PO类,例如User
- public class User implements Comparable<User>
- {
- private String name;
- private Integer age;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Integer getAger() {
- return age;
- }
- public void setAge(Integer age) {
- this.age= age;
- }
- public int compareTo(User arg0) {
- return this.getAge().compareTo(arg0.getAge());
- }
- }
- //测试客户端代码
- public static void main(String[] args) {
- User user1 = new User();
- user1.setName("zhangsan");
- user1.setAge(10);
- User user2 = new User();
- user2.setName("lisi");
- user2.setAge(6);
- List<User> list = new ArrayList<User>();
- list.add(user1);
- list.add(user2);
- Collections.sort(list); //排序
- for(User u : list){
- System.out.println(u.getName()); //输出
- }
- }
- lisi
zhangshan
第二种是封装类没有实现Comparable接口,此时需要在调用sort的另一个有参方法,依旧是这个封装类,但是没有实现Comparable,我这里就不写封装类,同上
- User user1 = new User();
- user1.setName("zhangsan");
- user1.setAge(10);
- User user2 = new User();
- user2.setName("lisi");
- user2.setAge(6);
- List<User> list = new ArrayList<User>();
- list.add(user1);
- list.add(user2); //初始化list
- Collections.sort(list,new new Comparator<User >(){
- //覆盖排序方法
- public int compare(User u1, User u2) {
- //按照User的年龄进行升序排列
- if(u1.getAge() > u2.getAge()){
- return 1;
- }
- if(u1.getAge() == u2.getAge()){
- return 0;
- }
- return -1;
- }
- }); //排序
如何应用Vector?
Vector与ArrayList在用法上几乎完全相同。但是它是线程安全的,也就是加了同步锁,相比之下性能会显得慢一些
那么在多线程下的ArrayList怎么样?
两个线程同时访问,对容器的同一位置进行了同一时刻的赋值,则会达不到希望容器产生的效果,比如
- 循环10000次在多线程可能会小于100000次
- 在ArrayList扩容的时候会造成数组越界,产生非常诡异的异常
Set接口及其实现类
Set集合类特点是什么?
- 无序集合
- 不允许包含重复元素,根据equals方法判断两个对象相同
如何应用Set接口的一个重要实现类HashSet呢
1.HashSet集合类的定义与添加集合元素
- HashSet集合添加一个元素时,会先得到该对象的hashCode值,然后通过equals方法判断集合内是否已存在相同的对象,如果已存在相同的对象,即hashcode指向的内存地址相同,则无法添加该对象。String字符串重写了equals方法,虽然str1(小明)与str2(小张)是两个不同的对象,但str1.equals(str2);返回是false,因此添加str2失败。
- HashSet是先比较元素的HashCode的值,也就是哈希值,如果哈希值相同的情况下,会调用equals方法比较两个元素的值是否相同。
- Set的另外一个实现类TreeSet则是通过调用CompareTo的方法,如果返回值为0,证明两个元素相同,因此TreeSet其实是一个有序的集合。
2.遍历集合元素
- HashSet集合只能通过Iterator接口或者增强for循环遍历集合元素,且因为HashSet不能保证元素的排列顺序,因而遍历读取集合元素的顺序是有可能发生变化的
- //增强for的方式
for(Person p:set){- System.out.println(p.name+p.age);
- }
3.删除元素
- set.remove(p1);
Map接口及其实现类
Map集合的特点是什么?
- 双列集合,保存两组值,一组是键key,另一组是值value,key和value之间存在单向一对一关系,通过指定的key,总能找到唯一的、确定的value
Map集合类的key不允许重复,根据equals方法判断两个key相同
Map集合类的key和value可以是任何类型的数据(键和值都可以为null)
如何应用HashMap?
- HashMap集合类添加键值对时,先根据equals方法判断要添加键值对的key是否存在,如果存在,value会发生覆盖,如果不存在,添加新的键值对。
遍历集合元素
1.keySet()方法获取元素
原理:
- 将Map集合中的所有键(Key)存入到Set集合中,因为Set集合具备迭代器,所以可以用迭代方式取出所有的键,再根据get方法获取每一个键对应的值。简单说就是:Map集合---->Set集合 ---->迭代器取出
2.entrySet()方法获取元素:
原理:
- 将Map集合中的映射关系(Key-Value)存入到了Set集合中,而这个映射关系的数据类型是Map.Entry,在通过迭代器将映射关系存入到Map.Entry集合中,并通过其中的getKey()和getValue()放取出键值。
其余还有其他遍历方式,比如说增强for,但是前提都是要获得Set存储Key的集合,即调用map.KeySet(),然后转化为String,在通过getValue("Key")的方式获取值,在实际开发当中比如获取数据库查询回来的ResultSet 都是rs,getString("字段名)
- 遍历得到结果的顺序并不是添加顺序,实际上,Map里的key和Set集合的存储形式(无序)类似,与HashSet集合不能保证元素的顺序一样,HashMap也不能保证其中key-value键值对的顺序。
删除集合元素
map.remove(key);
集合类之间的几种比较(小结)
1.Vector、ArrayList、LinkedList的异同?分别适用于何种需求?
ArrayList和Vector都是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许通过顺序索引查找元素,但是插入数据、删除数据要设计到数组元素移动等内存操作,所以查找数据快、增删数据慢。ArrayList和Vector在用法上几乎相同,但有一点明显区别:ArrayList是线程不安全的,多线程情况下,需要写代码保证集合的同步性;Vector是线程安全的,它使用了synchronized方法保证了多线程情况下集合的同步性;也正因为Vector的线程安全,它在性能上比ArrayList差。
LinkedList,首先它是一个List集合,可以根据索引来随机访问集合中的元素,这个与ArrayList的用法相同。除此之外,LinkedList采用双向链表实现存储,查找数据时需要进行向前或向后遍历,直到找到索引数据;但是插入数据时只需要记录本项的前后项即可,所以查找数据慢、增删数据快。
Arraylist 底层使用的是Object数组;LinkedList 底层使用的是双向链表数据结构(注意双向链表和双向循环链表的区别)
ArrayList的空 间浪费主要体现在在list列表的结尾会预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗比ArrayList更多的空间(因为要存放直接后继和直接前驱以及数据)
适用需求建议:
- 需要经常遍历集合元素,建议使用ArrayList、Vector
- 需要经常执行插入、删除操作来改变集合的大小,建议使用LinkedList
- 多线程的情况下,可以考虑Vector。但也可以考虑ArrayList,另外写代码保证集合的同步性
- 关于CopyOnWriteArrayList也是一个线程安全的容器,原理是
CopyOnWriteArrayList底层就是数组,加锁就交由ReentrantLock来完成。
在添加的时候就上锁,并复制一个新数组,增加操作在新数组上完成,将array指向到新数组中,最后解锁。
在修改时,复制出一个新数组,修改的操作在新数组中完成,最后将新数组交由array变量指向。
写加锁,读不加锁
2.HashSet与TreeSet的异同?分别适用于何种需求?
HashSet与TreeSet相同点:都是Set接口的实现类,集合元素都不允许重复;
HashSet与TreeSet不同点:
HashSet中的数据是无序的,可以放入null,且只能放入一个null,通过计算元素的hashCode值快速操作,所以HashSet的效率很高。
TreeSet中的数据是自动排序的,这个有序不同于List接口那样按照插入的先后顺序而且有对应的索引,这个顺序是按照元素对象自己定义的排序规则而定的。默认情况下,TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间大小关系,然后将集合元素按升序排列,基于TreeMap。因此,TreeSet中的每个对象的类都必须实现Comparable接口定义排序规则才可以正常使用,如String等这些类本身已经实现Comparable接口并有默认顺序,而null没有实现Comparable接口,所以TreeSet不允许放入null值。
3.HashMap、TreeMap、HashTable的异同?分别适用于何种需求?
HashMap和HashTable的关系类似于ArrayList和Vector的关系,HashTable与HashMap的用法基本相同,两者的区别有:
HashMap允许有空键(null)与空值(null),非线程安全,效率较高;
Hashtable不允许有空键(null)与空值(null),线程安全,效率较低;
TreeMap与HashMap的关系也类似与TreeSet和HashSet的关系,TreeMap实现SortMap接口,能够把它保存的键值对根据key排序,基于红黑树,从而保证TreeMap中所有键值对处于有序状态。TreeMap要求所有的key必须实现Comparable接口,默认遵循key的默认排序规则,也可以指定排序的比较器。当用Iterator 遍历TreeMap时,得到的记录是排过序的(类似TreeSet),不允许有空键(null)。
by the way
fail-fast 机制是java集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。抛java.util.ConcurrentModificationException
JAVA集合类兄妹List和Set的更多相关文章
- Java集合类--温习笔记
最近面试发现自己的知识框架有好多问题.明明脑子里知道这个知识点,流程原理也都明白,可就是说不好,不知道是自己表达技能没点,还是确实是自己基础有问题.不管了,再巩固下基础知识总是没错的,反正最近空闲时间 ...
- 做JavaWeb开发不知Java集合类不如归家种地
Java作为面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储.但是使用数组存储对象方面具有一些弊端,而Java 集合就像一种容器,可以动态地把多个对象的引用放入容 ...
- 【转载】Java集合类Array、List、Map区别和联系
Java集合类主要分为以下三类: 第一类:Array.Arrays第二类:Collection :List.Set第三类:Map :HashMap.HashTable 一.Array , Arrays ...
- 摘抄转载前辈们的Java集合类总结
本文摘自 Blue Sky:http://www.cnblogs.com/hubcarl JAVA 集合类介绍和使用 类关系示意图Iterable(接口) │ └--Collection (接口) ├ ...
- Java集合类简单总结(重学)
java集合类简介(重学) 一.Collection(集合).Map接口两者应该是平行关系吧. 1.Map介绍 Map是以键值(key-value)对来存放的,2个值.通过key来找到value(例: ...
- Java集合类中的哈希总结
JAVA集合类中的哈希总结 目 录 1.哈希表 2.Hashtable.HashMap.ConcurrentHashMap.LinkedHashMap.TreeMap区别 3.Hashtable.Ha ...
- Java集合类: Set、List、Map、Queue使用场景梳理
本文主要关注Java编程中涉及到的各种集合类,以及它们的使用场景 相关学习资料 http://files.cnblogs.com/LittleHann/java%E9%9B%86%E5%90%88%E ...
- Java 集合类详解(含类图)
0.参考文献 此图中蓝色为抽象类.深红色表示接口(Arrays除外).绿色表示具体容器类 1.java集合类图 1.1 1.2 上述类图中,实线边框的是实现类,比如ArrayList,LinkedLi ...
- Java集合类: Set、List、Map、Queue使用
目录 1. Java集合类基本概念 2. Java集合类架构层次关系 3. Java集合类的应用场景代码 1. Java集合类基本概念 在编程中,常常需要集中存放多个数据.从传统意义上讲,数组是我们的 ...
随机推荐
- datatable 笔记 服务器端查询
var vTable = ""; $("#vip_data").dataTable({ "scrollY": 400, //竖向高度 滚动 ...
- CAGradientLayer简介 实现颜色渐变
CAGradientLayer使用: CAGradientLayer*gradient = [CAGradientLayerlayer]; gradient.frame = subLayer.fram ...
- Ubuntu Server 12.04(14.04) 静态IP简洁配置
1.配置静态IP地址: # vim /etc/network/interfaces 原内容有如下4行:auto loiface lo inet loopback auto eth0iface eth0 ...
- 如何简单地理解Python中的if __name__ == '__main__'
https://blog.csdn.net/yjk13703623757/article/details/77918633 1. 摘要 通俗的理解__name__ == '__main__':假如你叫 ...
- 关系数据库数据与hadoop数据进行转换的工具 - Sqoop
Sqoop 本文所使用的Sqoop版本为1.4.6 1.官网 http://sqoop.apache.org 2.作用 A:可以把hadoop数据导入到关系数据库里面(e.g. Hive -> ...
- 将欢迎消息添加到PeopleSoft主页--登录事件
以下是如何为PeopleSoft应用程序设置Signon事件消息. 导航到PeopleTools>实用程序>管理> SignOn事件消息 在此页面上,您将看到当前处于活动状态或过去处 ...
- Microsoft Graph: Developer Blog
https://developer.microsoft.com/en-us/graph/blogs/announcing-30-days-of-microsoft-graph-blog-series/ ...
- php调用c/c++时 passthru()被禁用问题
passthru被禁用,需要编辑php.ini文件 disable_functions = scandir,passthru,exec,system,chroot,chgrp,chown,shell_ ...
- c#使用 Newtonsoft.Json 将entity转json时,忽略为null的属性
c#使用 Newtonsoft.Json 将entity转json时,忽略为null的属性,直接在属性上加下面的特性 [JsonProperty(NullValueHandling=NullValue ...
- 盒子模型/div标签/益出处理
/* <div></div>没有任何功能,不属于功能标签 可以放文字,图片以及各种元素的块标签 常常用来布局 span标签属于行内标签,无法设置宽高 */ <!docty ...