# 原创,转载请先留言

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方法试试:

@Override
public 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都是一个数,尝试一下:

@Override
public 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要注意的内容比较多,可以见我的另一篇博文:

java的collection集合的更多相关文章

  1. java 15-1 Collection集合的概述以及小功能介绍

     集合的由来:  我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储.  而要想存储多个对象,就不能是一个基本的变量,而应 ...

  2. Java 基础 - Collection集合通用方法及操作/ArrayList和LinkedList的差别优势 /弃用的Vector

    Collection的笔记: /**存储对象考虑使用: * 1.数组, ①一旦创建,其长度不可变!② 长度难于应对实际情况 * 2.Java集合, ①Collection集合: 1.set: 元素无序 ...

  3. Java的Collection集合的常用方法

    boolean add(E e) 添加元素到Collection集合中. boolean addAll(Collection<? extends E> c) 将指定c中的所有元素都添加到此 ...

  4. Java基础Collection集合

    1.Collection是所有集合的父类,在JDK1.5之后又加入了Iterable超级类(可以不用了解) 2.学习集合从Collection开始,所有集合都继承了他的方法 集合结构如图:

  5. Java基础知识强化之集合框架笔记05:Collection集合的遍历

    1.Collection集合的遍历 Collection集合直接是不能遍历的,所以我们要间接方式才能遍历,我们知道数组Array方便实现变量,我们可以这样: 使用Object[]  toArray() ...

  6. Java基础知识强化之集合框架笔记04:Collection集合的基本功能测试

    1. Collection集合的基本功能测试: package cn.itcast_01; import java.util.ArrayList; import java.util.Collectio ...

  7. Java Collection集合方法

    一.简单方法 package cn.itcast.day15; import java.util.ArrayList; import java.util.Arrays; import java.uti ...

  8. 万字长文深入理解java中的集合-附PDF下载

    目录 1. 前言 2. List 2.1 fail-safe fail-fast知多少 2.1.1 Fail-fast Iterator 2.1.2 Fail-fast 的原理 2.1.3 Fail- ...

  9. JAVA collection集合之 扑克牌游戏

    主要内容:这里使用collection集合,模拟香港电影中大佬们玩的扑克牌游戏. 1.游戏规则:两个玩家每人手中发两张牌,进行比较.比较每个玩家手中牌最大的点数,大小由A-2,点数大者获胜.如果点数相 ...

随机推荐

  1. cf 460 E. Congruence Equation 数学题

    cf 460 E. Congruence Equation 数学题 题意: 给出一个x 计算<=x的满足下列的条件正整数n的个数 \(p是素数,2 ≤ p ≤ 10^{6} + 3, 1 ≤ a ...

  2. 洛谷 P4556 [Vani有约会]雨天的尾巴 解题报告

    P4556 [Vani有约会]雨天的尾巴 题目背景 深绘里一直很讨厌雨天. 灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切. 虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒 ...

  3. webpack css压缩方案

    css-loader原有的minimize选项在1.0.0版本已经移除,不能使用其进行css压缩. 目前可行的css压缩方案有: 1. postcss-loader with cssnano or u ...

  4. ACE主动对象模式(1)

    转载于:http://www.cnblogs.com/TianFang/archive/2006/12/11/589168.html 主动对象模式用于降低方法执行和方法调用之间的耦合.该模式描述了另外 ...

  5. HTML学习基本代码

    HTML的代码比较繁琐,在此记下一些基本的东西,以后自己回来看看 <html> <head> <title>我的人生啊</title> <styl ...

  6. NYOJ 747贪心+dp

    蚂蚁的难题(三) 时间限制:2000 ms  |  内存限制:65535 KB 难度:4   描述 蚂蚁终于把尽可能多的食材都搬回家了,现在开始了大厨计划. 已知一共有 n 件食材,每件食材有一个美味 ...

  7. shell编程:条件测试与比较(六)

    条件测试方法综述 test条件测试的简单语法及测试 范例6-1 测试文件(在test命令中使用-f选项:文件存在且为不同文件则表达式成立) [root@adminset ~]# test -f fil ...

  8. SPOJ 104 HIGH - Highways

    HIGH - Highways http://www.spoj.com/problems/HIGH/ In some countries building highways takes a lot o ...

  9. [洛谷P2365] 任务安排

    洛谷题目链接:任务安排 题目描述 N个任务排成一个序列在一台机器上等待完成(顺序不得改变),这N个任务被分成若干批,每批包含相邻的若干任务.从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时 ...

  10. 【NOIP】提高组2015 子串

    [题意]求从字符串A中取出k个互不重叠的非空子串顺序拼接形成B的方案数.n<=1000,m<=100,k<=m. [算法]动态规划 [题解]这题主要是将从i-l转移变成从i-1转移, ...