Java集合框架(一)——集合概述

96
Mr_Yanger
2017.11.11 12:22* 字数 1673

本文概述

本篇文章将分三块内容对Java中的集合框架进行介绍:
一. 集合框架相关概念
二. 集合体系通用方法
三. 集合遍历—Iteractor

一. 集合框架相关概念

集合:用于存储多个对象的容器

1. 为什么使用集合

  在Java的世界中流行这么一句话:“一切皆对象”,任何事物都是以对象的形式体现。那有没有一种容器能够满足我们存储多个对象的需求呢?大家能想到的大概就是数组了,既然我们有了数组,那为什么还要使用集合呢?
  首先,虽然数组能够存储对象,但是一旦对数组进行初始化,其长度就无法改变。其次数组只能存储同一类型的对象,这两点注定了数组难以满足Java作为面向对象语言适应存储对象不断变化的需求,这时集合就发挥了他的优势。

2.集合的特点

  集合是一种只用于存储对象,但可以存储不同类型的对象,且长度可变的容器

3.数组和集合区别

  从对数组和集合的分析中可以总结出两者的区别:

  • 长度区别:
      - 数组长度不变
      - 集合长度可变
  • 内容不同
      -数组只能存储同一种类型的元素
      -集合可以存储不同类型的元素
  • 元素的数据类型
      -数组可以存储基本数据类型和引用数据类型
      -集合只能存储引用数据类型
4. 集合框架体系的形成

  满足上述需求之后,如果又有需求提出:在这个容器中我不要重复的元素,或者这么多元素我要有一定的排列顺序等等。
  针对不同的需求,Java提供了多种不同的集合类,多种集合类之间又有不同的数据结构(数据的存储方式),但同时他们又有共同的特性,比如存储和获取的功能,我们把这些集合的共性不断向上提取,最终形成了我们的继承体系结构

集合框架继承图(不完全)

二. 集合体系通用方法

在学习理论中,一个人学习一样技能一般方式:
分析:具体到抽象
实现:抽象到具体
使用:使用具体的

  所以对于集合体系的学习也可以从较为抽象的Collection接口开始学习,因为学习了Collection就相当于学习了所有集合的共性。既然集合是一个容器,作为容器的共同方法应该不外乎添加,删除,查看,判断和修改等功能。所以在Collection接口中应该会提供这些抽象方法,这时就需要打开万能的API文档进行学习。
  根据文档的查阅,我们可以将Collection中的方法分成以下几类(具体例子中以实现类ArrayList为例子):

1. 添加元素:

方法:
boolean add(E e);//添加一个对象,添加成功返回True
boolean addAll(Collection<? extends E> c);//添加一个集合中的所有元素

示例1:

public static void main(String args[]) {
        Collection c1 = new ArrayList();
        System.out.println("c1:" + c1);
        c1.add("Java");
        c1.add("Python");
        System.out.println("c1:" + c1);
}

输出结果1:

c1:[]
c1:[Java, Python]


示例2:

    public static void main(String args[]) {
        Collection c1 = new ArrayList();
        Collection c2 = new ArrayList();
        
        c1.add("Java");
        c1.add("Python");
        c2.add("Java");
        c2.add("wjy2");
        System.out.println("c1:" + c1);
        
        c1.addAll(c2);
        System.out.println("c1:" + c1);

输出结果

c1:[Java, Python]
c1:[Java, Python, Java, wjy2]


2. 删除元素:

方法:

boolean clear();//清除所有元素
boolean remove(Object o);//移除某个元素
boolean removeAll(Collection<? extends E> c);//移除一个集合中所包含的元素

示例1:

public static void main(String args[]) {
    Collection c1 = new ArrayList();
    c1.add("Java");
    c1.add("Python");
    System.out.println("c1:" + c1);

    c1.remove("Python");
    System.out.println("c1:" + c1);
}

输出结果1:

c1:[Java, Python]
c1:[Java]


示例2:

    public static void main(String args[]) {
        Collection c1 = new ArrayList();
        Collection c2 = new ArrayList();
        
        c1.add("Java");
        c1.add("Python");
        c2.add("Java");
        c2.add("wjy2");
        
        c1.removeAll(c2);
        System.out.println("c1:" + c1);

输出结果

c1:[Python]


3. 查找元素:

Iterator<E> iterator();//集合的遍历
Object toArray();//将集合转换成为数组,从而通过遍历数组的方式遍历集合

4. 判断内容:

方法:

boolean contains(object o);//集合中是否包括该元素
boolean contains(Collection<? extends E> c);//集合中是否包括该集合
boolean isEmpty();//判断集合是否为空
int size();//集合中元素的数量

示例:

    public static void main(String args[]) {
        Collection c1 = new ArrayList();
        Collection c2 = new ArrayList();
        
        c1.add("Java");
        c1.add("Python");
        c2.add("Java");
        c2.add("wjy2");
        
        System.out.println(c1.contains("xxx"));
        System.out.println(c1.containsAll(c2));
        System.out.println(c1.size());
        System.out.println(c1.isEmpty());   
    }

输出结果:

false
false
2
false


思考:String类和Array类中判断长度是使用size()方法,还是length()方法,还是length属性呢?


5. 修改元素

方法:

boolean retainAll(Collection<? extends E> c);//取两个集合的交集,直接会对元素本身产生作用

示例:

    public static void main(String args[]) {
        Collection c1 = new ArrayList();
        Collection c2 = new ArrayList();
        
        c1.add("Java");
        c1.add("Python");
        c2.add("Java");
        c2.add("wjy2");
        
        c1.retainAll(c2);
        System.out.println("c1:" + c1);
}

输出结果:

c1:[Java]


注意:该方法会在原有集合上做出改变,只要原来的集合有改动就会返回True


三. 集合遍历—Iteractor

1. 集合遍历的方法

  还记得集合体系图中最上层的接口Iterable吗?
  我们可以通过Iterator来进行集合的遍历,使用while和for语句的代码如下:

while语句方法:

public static void main(String args[]) {
        Collection c1 = new ArrayList();
        c1.add(new Student("张三",18));
        c1.add(new Student("李四",28));
        c1.add(new Student("王五",38));
        c1.add(new Student("赵六",48));

        Iterator iter = c1.iterator();
        while(iter.hasNext()) {
            Student s = (Student) iter.next();
            System.out.println(s.getName() + "---------" + s.getAge());
        }
    }

for语句方法:

for(Iterator iter = c1.iterator();iter.hasNext();) {
        Student s = (Student) iter.next();
        System.out.println(s.getName() + "---------" + s.getAge());
    }

输出结果:

张三---------18
李四---------28
王五---------38
赵六---------48


  从两种方法中不难发现,使用while方法代码非常清晰,具有良好的可读性。使用for方法可读性不如前者,但是能够在一次循环中很快的将Iterator对象变成内存垃圾,及时回收,效率更高。
  具体使用哪种方法完全看个人喜好,所以不必纠结。

我们来总结一下集合的使用步骤:
  1. 创建集合对象
  2. 创建元素对象
  3. 把元素添加到集合当中
  4. 通过Iterator遍历集合
    - 通过集合对象获取迭代器
    - 通过迭代器中hasNext()方法判断是否又元素
    - 通过迭代器对象next()获取元素并移动到下一个位置

2. 从原理层面理解Iterator集合遍历

  学会了遍历的基本格式是不够的,还需要从源码角度理解Iterator的使用机制,才能够更好掌握集合的遍历。
  Interator在源码中的框架大致是这样的:

public interface Iterator{
        public abstract boolean hasNext();
        public abstract Object next();
}
public interface Iterable{
        Iterator iterator();
}
public interface Collection extends Iterable{
}
public interface List extends Collection{
}
public class ArrayList implements List{
}

  迭代器之所以定义成接口而不是一个类,是因为Java中提供了很多集合类,而这些集合类的数据结构是不同的,存储方式和遍历方式也是不同的,所以最终迭代器被设计为了接口。最终的实现方法不在Collection中,不再List中,而是在具体的实现子类ArrayList中才得以实现。

  而无论是集合本身还是集合遍历,都体现出Java作为面向对象语言所具备的继承,多态的特性,体现这Java设计语言本身的智慧与魅力。
  本文对集合框架做了简单的概述,之后的文章会对集合具体的实现类做更深入的介绍,欢迎继续观看后续内容,一起体会Java语言的智慧与魅力。

Java程序设计系列教程
Web note ad 1