# 原创,转载请先留言

1.集合的由来

数组的长度是固定的,当需要增加或减少元素时需要对数组重新定义,太麻烦了。java内部给我们提供了集合类,能存储任意对象,长度可以改变的,随着元素的增加而增加,随着元素的减少而减少。

2.数组和集合的区别

(1)数组既可以存储基本数据类型,又可以存储引用数据类型(存储基本数据类型时存储的是值,存储引用数据类型的是地址值)。集合只能存储引用数据类型,但是实际用的时候可以存储基本数据类型,为什么呢?(是因为在存储的时候进行了自动装箱,例如 int 自动装箱为integer)

(2)数组长度是固定的,不能自动增长。集合的长度是可变的,根据元素的增加而增长。

3.数组和集合什么时候用

(1)如果元素个数是固定的推荐用数组(为什么不一直用集合呢?举个例子,你要存储固定的50个元素,用数组直接划分50个空间就可以存储了。但是用集合的话,例如,某些集合的底层原理是使用数组做的[ArrayList],他会先创建10个空间,不够再增长到1.5倍,到15,再不够再增长,效率低。)

(2)如果元素个数不是固定的推荐用集合

4.集合继承体系

看API文档可以知道Collection是接口。

而且还有两大子类接口List和Set。

List和Set下会有各种实现类。如下图:

5.各个接口或类常用方法

  • Collection接口

Collection是一个接口,所以不能实例化,即不能创建对象。

Collection有几个常见的接口方法,可以体验一下:

boolean add(E e)  添加元素

boolean remove(Object o)   删除元素

void clear()  清除集合

boolean contains(Object o)  是否包含

boolean isEmpty()  是否为空集合

int size()  集合元素的个数

object[] toArray  把集合转换为对象数组

boolean addAll(Collection<? extends E> c)    把另一个集合的元素添加到该集合

boolean removeAll(Collection<?> c)    删除指定集合中包含的所有此集合的元素

boolean containsAll(Collection<?> c)    如果此集合包含指定 集合中的所有元素,则返回true

boolean retainAll(Collection<?> c)   仅保留此集合中包含在指定集合中的元素(注意这个返回值比较反人类,后面示例2验证)

Iterator<E> iterator()    返回集合的迭代器

示例1:(toArray方法)

public static void main(String[] args) {Collection c = new ArrayList();c.add(new Students("张三",13));  // 这里其实实现了自动装箱,Object o = new Students("张三",13),因为add的参数是Object对象c.add(new Students("李四",14));c.add(new Students("王五",15));//遍历集合,先把集合转化为数组,然后遍历Object[] arr= c.toArray();   // 注意返回值是Object对象,不是Students对象for (int i = 0;i < arr.length;i++){// 如果要用到子类的特有的属性或者方法,比较向下转型为子类对象Students s = (Students) arr[i];System.out.println(s.getName() + "---" + s.getAge());  // 当然,你也可以重写toString方法直接输出,就不用向下转型了
        }}

示例2:(retainAll方法)

 public static void main(String[] args) {Collection c = new ArrayList();c.add(100);c.add(200);c.add(300);Collection c2 = new ArrayList();c2.add(100);c2.add(200);c2.add(300);
//        c2.add(400);Boolean flag = c.retainAll(c2);   // 返回值有点古怪!c如果变化了,就是true。如果没变化就是false
        System.out.println(c);System.out.println(flag);}

  • List接口

List是一个接口,不能实例化。

List有几个Collection没有的接口方法。

void add(int index,E element)    在指定索引添加元素

E remove(int index)    删除指定索引的元素

E get(int index)    获取指定索引的元素

E set(int index,E element)    修改指定索引的值

易错点:(remove方法)

public static void main(String[] args) {List l = new ArrayList();l.add(100);l.add(200);l.add(300);/*IndexOutOfBoundsException.注意,虽然Colletion有这个remove(Object o)接口方法,但是remove([如果是int类型])不会自动装包,所以输入数字的时候默认是index。但是如果是其他类型是可以的。*/l.remove(100);System.out.println(l);}

  • ArrayList、LinkedList、Vetor类

ArrayList类底层是数组实现的。线程不安全,效率高。查询修改快,增删慢。

Vetor类底层是数组实现的。线程安全,效率低。查询修改快,增删慢。(基本已经被ArrayList取代了)

LinkList类底层是链表实现的。线程不安全,效率高。增删快,查询修改慢。

* 如果增删多用LinkedList,如果查询修改多用ArrayList

  • Set接口

打开API文档看了下,set接口的接口方法基本上和Collection的接口一样,所以可以set接口方法的使用可以参考上面的Collection接口方法。

  • HashSet类

HashSet类是Set接口的实现类。HashSet只能存储不同的元素、

boolean add(E e)    将指定的元素添加到此集合(如果尚未存在)

但是add对象的时候出现了问题:

public static void main(String[] args) {HashSet<Students> hs = new HashSet<>();hs.add(new Students("张三",13));hs.add(new Students("张三",13));hs.add(new Students("李四",14));hs.add(new Students("李四",14));hs.add(new Students("李四",14));for (Students s:hs) {System.out.println(s);}}// 输出结果:
Students{name='张三', age=13}
Students{name='李四', age=14}
Students{name='李四', age=14}
Students{name='张三', age=13}
Students{name='李四', age=14}

如果我们把同名与同年龄的看做同一个对象,希望输出结果只有张三,李四呢?

根据ArrayList遇到这种情况的时候,第一时间想到了equals方法,重写equals方法试试:

@Overridepublic boolean equals(Object obj) {    Students s = (Students)obj;return this.name.equals(s.name)  && this.age == s.age;}

运行,发现并不可行,输出结果还是那个。问题出在哪里?

其实HashSet的判断方式是这样的,先判断hashCode,如果hashCode一样,才会判断equals方法。如果hashCode不一样,那么直接认为他们是不一样的。

我们先让Students对象的hashCode都是一个数,尝试一下:

@Overridepublic int hashCode() {return 10;}

发现结果符合我们的预期了,返回的是张三、李四两个对象。是因为大家的hashCode都一样,然后就运行equals方法进行比较。

但是这样的话,hashCode的方法就完全没有意义了。而且每次都会运行equals方法,效率很低。设想这么一个场景,每个对象都是不一样的,然而返回的哈希值一样,然后每一个都运行equals方法进行比较,效率十分低。

最理想的状态就是运行hashCode方法时相同的对象就是相同的值,不同的对象就是不同的值。这样才是最高效率的。而equals方法只是一个后备,万一不同的对象算出来的哈希值一样,equals方法才用的上。所以必须hashCode方法与equals方法都必须重写!

比较重要的是要想办法重写一个漂亮的hashCode方法。但是IDE已经帮我们完成了这个- -

IDEA下Alt+Insert选择equals and hashCode就行了。

  • LinkedHashSet类(上面的图没有画出来)

LinkedHashSet是HashSet的子类,用法基本和HashSet一样。LinkedHashSet底层是用链表与哈希表实现。LinkedHashSet最大的特点就是它是Set族中唯一一个能怎么存怎么取的。

  • TreeSet集合

TreeSet集合可以对元素进行排序,当然也可以保证元素的唯一。

关于TreeSet要注意的内容比较多,可以见我的另一篇博文:

转载于:https://www.cnblogs.com/chichung/p/10239332.html

java的collection集合相关推荐

  1. 【Java】Collection集合和泛型

    学习目标:会存取,掌握特性 学习方式:学习顶层接口/抽象类的共性方法,使用底层的子类创建对象使用 1 集合框架 集合类的继承体系: Collection接口: ·············1) List ...

  2. Java基础-Collection集合接口(List及Set)

    Collection集合接口 1.Collection接口的常用方法 2.Collection集合迭代 3.contains方法解析 4.集合中元素的删除 5.List接口的特有方法 6.Set接口 ...

  3. JAVA day15 Collection(集合)、Iterator迭代器、泛型<E>

    1.Collection(集合) 集合:集合是java中提供的⼀种容器,可以⽤来存储多个数据. 集合与数组的区别: 数组的长度是固定的,集合的长度是可变的. 数组中存储的是同⼀类型的元素,可以存储基本 ...

  4. Java 基础 Collection集合

    package cn.itcast.demoDateformat;import java.util.ArrayList; import java.util.Collection;/* * List接口 ...

  5. Java 基础 Collection集合拓展

    package cn.itcast.demoDateformat;import java.util.ArrayList; import java.util.Collection; import jav ...

  6. Java中Collection集合常用API - Collection存储自定义类型对象

    文章目录 Collection常用API Collection存储自定义类型对象 Collection常用API Collection集合API Collection是单列集合的祖宗接口,因此它的功能 ...

  7. Java中Collection集合接口

    在Java中有数组,但数组不能存储引用变量.所以数组用得不是很多,一般Java中用继承Collection接口的实现类比较多.其中List接口和Set接口继承了Collection接口,而Map接口并 ...

  8. java中Collection集合成员花名册

    java2提出了collection的概念,本文对collection框架进行分析,并对java2之前的容器进行回顾. 0x01 从Arraylist说起 什么是集合,简单地说,集合类似可以自适应.动 ...

  9. [Java基础]Collection集合

    Collection:

最新文章

  1. android 超链接事件,Android实现捕获TextView超链接的方法
  2. iptables白名单配置
  3. Run service in specified proxyPort via jettyrun
  4. mybatis insert 忽略 联合唯一索引_MySQL实战中,Insert语句的使用心得总结
  5. Tomcat7性能优化
  6. 并查集一般高级应用的理解
  7. 在Ubuntu 12.04安装和设置Samba实现网上邻居共享
  8. 机器学习之开源库大总结
  9. 2017-2018-1 20155227 《信息安全系统设计基础》第四周学习总结
  10. c#读取csv到数组_C#读取CSV
  11. Uncaught TypeError: Cannot read property 'tagNa...
  12. 听我讲完 redo log、binlog 原理,面试官老脸一红!
  13. Latex tabular和tabular* 注意表格样式参数命令
  14. 【技术讨论】从弹弹堂说起,如何用2D物理引擎编写一个游戏lt;一gt;2011-11-05 10:36
  15. GBin1分享:25个超酷手绘插图的网站设计
  16. java后台获取Excel后缀名以及sheet页名称
  17. 线性方程解法(齐次,非齐次)
  18. android shp开源,开源GIS Sharpmap及其shp资源
  19. 信息收集(二) 站长工具 ZoomEye
  20. android免费商用图标,免费商用!!!(线性图标)

热门文章

  1. c语言链表删除前一个节点,最简单的链表删除第一个节点时释放内存的问题
  2. python游戏编程入门书籍推荐-游戏编程入门书籍推荐:想要游戏编程尽快入门这些书不要错过...
  3. python入门只需20分钟-史上最详细python学习路线-从入门到精通,只需5个月时间...
  4. python零基础入门教材-Python零基础入门到精通自学视频教程
  5. python绘制曲线图-python怎么画曲线图
  6. 零基础编程入门python视频-Python编程零基础小白快速入门完整全系列精品课
  7. python爬虫百科-Python从概念上先了解爬虫
  8. php和python和java-python与java区别
  9. python话雷达图-python使用matplotlib绘制雷达图
  10. 0基础学python-如何从零基础自学Python?