18.java 容器都有哪些?

2022-06-21 00:00:00 容器 都有哪些 18.

JAVA容器类概述

1.常用容器分类

《18.java 容器都有哪些?》
JAVA中的容器类主要分为两大类,一类是Map类,一类是Collection类,他们有一个共同的父接口Iterator,它提供基本的遍历,删除元素操作。Iterator还有一个子接口LinkIterator,它提供双向的遍历操作。

Collection是一个独立元素的序列,这些元素都服从一条或多条规则,它有三个子接口List,Set和Queue。其中List必须按照插入的顺序保存元素、Set不能有重复的元素、Queue按照排队规则来确定对象的产生顺序(通常也是和插入顺序相同)

Map是一组成对的值键对对象,允许用键来查找值。它允许我们使用一个对象来查找某个对象,也被称为关联数组,或者叫做字典。它主要包括HashMap类和TreeMap类。Map在实际开发中使用非常广,特别是HashMap,想象一下我们要保存一个对象中某些元素的值,如果我们在创建一个对象显得有点麻烦,这个时候我们就可以用上Map了,HashMap采用是散列函数所以查询的效率是比较高的,如果我们需要一个有序的我们就可以考虑使用TreeMap。

2.Iterator类

迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。

Java中的Iterator功能比较简单,并且只能单向移动:

(1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。

(2) 使用next()获得序列中的下一个元素。

(3) 使用hasNext()检查序列中是否还有元素。

(4) 使用remove()将迭代器新返回的元素删除。

接口代码如下:

public interface Iterator<E> {     
public boolean hasNext();    
public E next();    
public void remove();}

Iterator可以不用管底层数据具体是怎样存储的,都能够通过next()遍历整个容器,那么它是如何实现的呢?我们来具体分析下Java里AbstractList实现Iterator的源代码:

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {  
// List接口实现了Collection<E>, Iterable<E> 
  
    protected AbstractList() {   
    }  
    
    ...  
  
    public Iterator<E> iterator() {   
    return new Itr();  // 这里返回一个迭代器
    }  
  
    private class Itr implements Iterator<E> {   // 内部类Itr实现迭代器
       
    int cursor = 0;  
    int lastRet = -1;  
    int expectedModCount = modCount;  
  
   public boolean hasNext() {   // 实现hasNext方法
           return cursor != size();  
    }  
  
    public E next() {   // 实现next方法
            checkForComodification();  
        try {   
        E next = get(cursor);  
        lastRet = cursor++;  
        return next;  
        } catch (IndexOutOfBoundsException e) {   
        checkForComodification();  
       throw new NoSuchElementException();  
        }  
    }  
  
    public void remove() {   // 实现remove方法
        if (lastRet == -1)  
        throw new IllegalStateException();  
            checkForComodification();  
  
        try {   
        AbstractList.this.remove(lastRet);  
        if (lastRet < cursor)  
            cursor--;  
        lastRet = -1;  
        expectedModCount = modCount;  
       } catch (IndexOutOfBoundsException e) {   
       throw new ConcurrentModificationException();  
        }  
    }  
  
    final void checkForComodification() {   
        if (modCount != expectedModCount)  
        throw new ConcurrentModificationException();  
    }  
    }  
}

可以看到,实现next()是通过get(cursor),然后cursor++,通过这样实现遍历。

这部分代码不难看懂,唯一难懂的是remove操作里涉及到的expectedModCount = modCount;

在网上查到说这是集合迭代中的一种“快速失败”机制,这种机制提供迭代过程中集合的安全性。

从源代码里可以看到增删操作都会使modCount++,通过和expectedModCount的对比,迭代器可以快速的知道迭代过程中是否存在list.add()类似的操作,存在的话快速失败!

参考文章1
参考文章2
参考文章3
参考文章4
参考文章5
参考文章6
参考文章7

参考文章8

    原文作者:peakyu
    原文地址: https://blog.csdn.net/py1215/article/details/107611541
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

相关文章