Java集合源码探究之遍历方式,SetList Map

    科技2022-07-12  148

    迭代器接口

    类图

    迭代器是一个接口, 首先看一下java对迭代器接口的描述信息,以及这个接口定义的基本规范

    迭代器接口的描述, 基本规范

    实现这个接口, 允许一个对象成为深度 for - each 的目标。并且能够使用泛型。

    iterator 返回一个迭代器 forEach(Consumer<? super T> action) 对每一个元素演示提供的动作, 直到所有的元素全部通过或者有一个元素抛出异常, 除非实现类有其他的规定,迭代器将按照顺序执行,操作引发的异常被中继到调用方。 default 在接口中可以使用default关键字来修饰一些默认实现的方法。 public interface Iterable<T> { Iterator<T> iterator(); default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } default Spliterator<T> spliterator() { return Spliterators.spliteratorUnknownSize(iterator(), 0); } }

    测试

    public class test implements Iterable<Integer> { @Override public Iterator<Integer> iterator() { return null; } @Override public void forEach(Consumer<? super Integer> action) { action.accept(3); } @Override public Spliterator<Integer> spliterator() { return null; } public static void main(String[] args) { test test = new test(); test.forEach(System.out::println); } }

    对迭代器简单探究

    ArrayList

    迭代器方式

    Collection接口也是迭代器接口的子接口, 则其必须对迭代器接口中做出的规范进行实现,下面进行简单的探究, 在java的集合框架中, 会存在一个简单的三层模型, 分别是

    最上层的接口 定义规范 中间层的抽象类 对一些特殊的规范做出统一(或者特殊)的实现 最下层的具体实现类 根据自己的特电重写实现类中的实现, 和最上层接口中定义的规则。

    对于这三层,将通过ArrayList进行探究, 先看下类图

    ArrayList 继承 AbstractListAbstractList 继承 AbstractCollection AbstractList 实现 List 接口 AbstractColleciont 实现 Collection

    Collection 接口

    我们先看下 Collection 接口中迭代器相关的。几乎没有对迭代器接口做出任何的改动, 最上层的接口用来定义规范!

    Iterator<E> iterator(); @Override default Spliterator<E> spliterator() { return Spliterators.spliterator(this, 0); }

    AbstractColleciont 实现类

    AbstractColleciont 这给抽象类也只是对 Collection 中的一些普遍方法做出了一些实现,对于迭代器部分也是没做出修改。

    public abstract Iterator<E> iterator();

    List接口

    此接口中又定义了一个ListIterator 的方法, 用作List集合的迭代!

    ListIterator<E> listIterator(); ListIterator<E> listIterator(int index);

    AbstractList 实现类

    在这个抽象类中终于看到了关于迭代器的部分!可以看到最上层的迭代器方法中返回了一个迭代器对象!按照内部类的方式进行返回, 来探究以下其中的方法实现!

    cursor 记录着我们通过迭代器返回了几个元素 lastRet 记录这我们最后一个返回元素的位置 expectedModCount 我们期望被修改的次数, 用来判断并发! public boolean hasNext() 和 cursor 以及 size() 方法一起来判断是否还有下一个元素 public E next() 返回下一个元素 public void remove()删除最近遍历的元素 public Iterator<E> iterator() { return new Itr(); } private class Itr implements Iterator<E> { int cursor = 0; int lastRet = -1; int expectedModCount = modCount; public boolean hasNext() { return cursor != size(); } public E next() { checkForComodification(); try { int i = cursor; E next = get(i); lastRet = i; cursor = i + 1; return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } public void remove() { if (lastRet < 0) 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(); } }

    arrayList 类

    方法实现上基本和AbstractList 类似, 只不过多了具体 forEachRemaining(Consumer<? super E> consumer) 的实现, 以及forEach的重写(重写的是迭代器接口中默认的实现)

    forEach 其中遍历集合中的每一个元素, 对其进行我们的action! @Override public void forEach(Consumer<? super E> action) { Objects.requireNonNull(action); final int expectedModCount = modCount; @SuppressWarnings("unchecked") final E[] elementData = (E[]) this.elementData; final int size = this.size; for (int i=0; modCount == expectedModCount && i < size; i++) { action.accept(elementData[i]); } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } } public Iterator<E> iterator() { return new Itr(); } private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; Itr() {} public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } @Override @SuppressWarnings("unchecked") public void forEachRemaining(Consumer<? super E> consumer) { Objects.requireNonNull(consumer); final int size = ArrayList.this.size; int i = cursor; if (i >= size) { return; } final Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) { throw new ConcurrentModificationException(); } while (i != size && modCount == expectedModCount) { consumer.accept((E) elementData[i++]); } // update once at end of iteration to reduce heap write traffic cursor = i; lastRet = i - 1; checkForComodification(); } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }

    List类

    迭代器遍历for 循环遍历forEach遍历 public static void main(String[] args) { Integer[] ints = {1, 2, 3, 4}; ArrayList<Integer> integers = new ArrayList<Integer>(Arrays.asList(ints)); Iterator<Integer> iterator = integers.iterator(); iterator.next(); iterator.remove(); while (iterator.hasNext()) { System.out.println("while"); System.out.println("->" + iterator.next()); } integers.forEach(System.out::println); for (int i = 0; i < integers.size(); i++) { System.out.println(integers.get(i)); } }

    Set类

    set.iterator();set.toArray(); public static void main(String[] args) { HashSet<Integer> set = new HashSet<>(); set.add(2); set.add(3); set.add(4); set.add(5); Iterator<Integer> iterator = set.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } for (Integer integer : set) { System.out.println(integer); } Object[] toArray = set.toArray(); for (Object o : toArray) { System.out.println(o); } }

    Map类

    map.keySet();map.values();map.entrySet(); public static void main(String[] args) { HashMap<String, Object> map = new HashMap<>(); map.put("1", "1"); map.put("2", "2"); Set<Map.Entry<String, Object>> entries = map.entrySet(); for (Map.Entry<String, Object> entry : entries) { System.out.println(entry.getKey() + "- >" + entry.getValue()); } Set<String> strings = map.keySet(); for (String string : strings) { System.out.println(string); } Collection<Object> values = map.values(); for (Object value : values) { System.out.println(value); } }
    Processed: 0.012, SQL: 8