浅谈Java中的集合

集合概述

面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,Java就提供了集合类。

数组和集合的区别:

  • 长度区别:
    数组的长度是固定的;集合的长度是可变的
  • 存储数据类型的区别:
    数组可以存储基本数据类型,也可以存储引用数据类型数据;集合只能存储引用数据类型
  • 内容区别:
    数组只能存储同种数据类型的元素;集合可以存储不同类型的元素

Collection集合

Collection集合是集合的顶层父接口,其继承体系如图:

下面先谈谈Collection集合吧。

Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。

成员方法

将成员方法按功能分:
添加功能

  • boolean add(Object obj):添加一个元素
  • boolean addAll(Collection c):添加一个集合的元素 (给一个集合添加进另一个集合中的所有元素)

删除功能

  • void clear():移除所有元素
  • boolean remove(Object o):移除一个元素
  • boolean removeAll(Collection c):移除一个集合的元素(移除一个以上返回的就是true) 删除的元素是两个集合的交集元素,如果没有交集元素 则删除失败 返回false

判断功能

  • boolean contains(Object o):判断集合中是否包含指定的元素
  • boolean containsAll(Collection c):判断集合中是否包含指定的集合元素(这个集合 包含 另一个集合中所有的元素才算包含 才返回true)
  • boolean isEmpty():判断集合是否为空

获取功能

  • Iterator iterator()(迭代器)

长度功能

  • int size():元素的个数

交集功能

  • boolean retainAll(Collection c):获取两个集合的交集元素(交集:两个集合都有的元素)

把集合转换为数组

  • Object[] toArray()

集合元素的遍历
当集合的对象使用Collection类型来接收的时候,对于集合中的元素的遍历,有两种方式:

  • 将集合转为数组,再进行遍历
public class Demo6 {
    public static void main(String[] args) {
        // 将3个学生的信息存储到数组中,并遍历数组,获取得到每一个学生信息
        Student s1 = new Student("张三", 23);
        Student s2 = new Student("李四", 21);
        Student s3 = new Student("王五", 22);
        Collection arrayList = new ArrayList();
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        Object[] objects = arrayList.toArray();
        for (int i = 0; i < objects.length; i++) {
            Student stu= (Student) objects[i];
            System.out.println(stu.getName()+"----"+stu.getAge());
        }
    }
}

class Student{
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

  • 使用迭代器进行遍历
    先获取迭代器,再判断是否有下一个元素(hasNext()方法),有的话就获取下一个元素(next()方法)。
public class Demo6 {
    public static void main(String[] args) {
        // 将3个学生的信息存储到数组中,并遍历数组,获取得到每一个学生信息
        Student s1 = new Student("张三", 23);
        Student s2 = new Student("李四", 21);
        Student s3 = new Student("王五", 22);
        Collection arrayList = new ArrayList();
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        // 使用迭代器进行遍历
        Iterator iterator = arrayList.iterator();   // 获取迭代器
        while (iterator.hasNext()){    
            Object o = iterator.next();
            Student stu = (Student) o;
            System.out.println(stu.getName()+"----"+stu.getAge());
        }
       
    }
}

List集合


List中的元素特点:元素有序,并且每一个元素都存在一个索引。元素可以重复。

List集合的特有功能

由于List继承了Collection,所以Collection的方法List都可以使用,但它还有自己独特的功能。




常用的方法
void add(int index,E element):在指定索引处添加元素
E remove(int index):移除指定索引处的元素 返回的是移除的元素
E get(int index):获取指定索引处的元素
E set(int index,E element):更改指定索引处的元素 返回的而是被替换的元素

集合元素的遍历
当集合的对象使用List类型来接收的时候,对于集合中的元素的遍历,有以下几种方式:

  • 由于List是Collection的子接口,所以Collection遍历元素的方式,List完全可以用。即可以将集合转换成数组,可以使用Collection的迭代器进行遍历。
  • 由于List中有自己独特的迭代器(ListIterator),所以也可以使用List自己的迭代器来进行遍历。
public class Demo6 {
    public static void main(String[] args) {
        // 将3个学生的信息存储到数组中,并遍历数组,获取得到每一个学生信息
        Student s1 = new Student("张三", 23);
        Student s2 = new Student("李四", 21);
        Student s3 = new Student("王五", 22);
        //List arrayList = new ArrayList();
        Collection arrayList = new ArrayList();
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        // 使用列表迭代器进行遍历
        ListIterator listIterator = arrayList.listIterator();
        while (listIterator.hasNext()){
            Object next = listIterator.next();
            Student student= (Student) next;
            System.out.println(student.getName()+"----"+student.getAge());
        }
     
    }
}

class Student{
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

需要注意的是,ListIterator 继承自Iterator 可以使用Iterator中的方法,同时,ListIterator有自己的特有功能:
boolean hasPrevious(): 是否存在前一个元素
E previous(): 返回列表中的前一个元素

以上两个方法可以实现反向遍历 但是注意 要完成反向遍历之前 要先进行正向遍历 这样指针才能移到最后。如果直接反向遍历是没有效果的 因为指针默认位置就在最前面,他前面没有元素。

  • List中有一个get()方法,用于获取对应索引处的元素值。所以可以结合size()方法和get()方法来进行遍历。
public class Demo6 {
    public static void main(String[] args) {
        // 将3个学生的信息存储到数组中,并遍历数组,获取得到每一个学生信息
        Student s1 = new Student("张三", 23);
        Student s2 = new Student("李四", 21);
        Student s3 = new Student("王五", 22);
        //List arrayList = new ArrayList();
        Collection arrayList = new ArrayList();
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        // 使用size和get方法进行遍历
        for (int i = 0; i < arrayList.size(); i++) {
            Object o = arrayList.get(i);
            Student student= (Student) o;
            System.out.println(student.getName()+"----"+student.getAge());
        }
    }
}

class Student{
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

List下有多个子类,但常用的子类有ArrayList、Vector、LinkedList。
这三个子类的特点为:

  • ArrayList
    底层数据结构是数组,查询快,增删慢
    线程不安全,效率高
  • Vector
    底层数据结构是数组,查询快,增删慢
    线程安全,效率低
  • LinkedList
    底层数据结构是链表,查询慢,增删快
    线程不安全,效率高

那么问题来了,在这三个类中我们该如何选择使用呢?
看我们程序的需求,是要安全还是要效率以及是要查找多还是增删多,依据这些来选择我们需要使用的子类。

下面来谈谈这三个子类。

ArrayList


List 接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。
每个 ArrayList 实例都有一个容量。该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向 ArrayList 中不断添加元素,其容量也自动增长。并未指定增长策略的细节,因为这不只是添加元素会带来分摊固定时间开销那样简单。

构造方法

成员方法

集合元素的遍历
由于ArrayList是List的子类,所以可以使用转换成数组迭代器以及size()和get方法结合的方式进行元素的遍历,除此之外还可以用JDK1.8新增的一个方法void forEach(Consumer<? super E> action) 遍历元素。
void forEach(Consumer<? super E> action) 执行特定动作的每一个元素的 Iterable直到所有元素都被处理或操作抛出异常 。

Vector


Vector 类可以实现可增长的对象数组, Vector 是同步的。与数组一样,它包含可以使用整数索引进行访问的组件。但是,Vector 的大小可以根据需要增大或缩小,以适应创建 Vector 后进行添加或移除项的操作。
构造方法
在这里插入图片描述

成员方法



LinkedList


List 接口的链接列表实现,此实现不是同步的。实现所有可选的列表操作,并且允许所有元素(包括 null)。除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。

构造方法

成员方法



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章