Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 增强的for语句如何用于数组,以及如何获取数组的迭代器?_Java_Arrays_Iterator_Foreach - Fatal编程技术网

Java 增强的for语句如何用于数组,以及如何获取数组的迭代器?

Java 增强的for语句如何用于数组,以及如何获取数组的迭代器?,java,arrays,iterator,foreach,Java,Arrays,Iterator,Foreach,给定以下代码段: int[] arr = {1, 2, 3}; for (int i : arr) System.out.println(i); 我有以下问题: 上述每个循环是如何工作的 如何在Java中获得数组的迭代器 数组是否转换为列表以获取迭代器 不,没有转换。JVM只是在后台使用索引遍历数组 有效Java第二版第46项的报价: 请注意,使用此选项不会导致性能损失 对于每个循环,甚至对于阵列,都会使用。事实上,它可能会提供一点性能优势 在某些情况下,在普通for循环上,因为它计算

给定以下代码段:

int[] arr = {1, 2, 3};
for (int i : arr)
    System.out.println(i);
我有以下问题:

  • 上述每个循环是如何工作的
  • 如何在Java中获得数组的迭代器
  • 数组是否转换为列表以获取迭代器

  • 不,没有转换。JVM只是在后台使用索引遍历数组

    有效Java第二版第46项的报价:

    请注意,使用此选项不会导致性能损失 对于每个循环,甚至对于阵列,都会使用。事实上,它可能会提供一点性能优势 在某些情况下,在普通for循环上,因为它计算 数组索引只有一次

    因此,无法为数组获取
    迭代器(当然,除非首先将其转换为
    列表)


    或者编写自己的,实现ListIterator接口。

    您不能直接为数组获取迭代器

    但您可以使用数组支持的列表,并在该列表上获取一个ierator。为此,数组必须是整数数组(而不是int数组):

    Integer[]arr={1,2,3};
    List arrAsList=Arrays.asList(arr);
    迭代器iter=arrAsList.Iterator();
    
    注:这只是理论。您可以得到这样的迭代器,但我不鼓励您这样做。与使用“extended for syntax”在数组上直接迭代相比,性能并不好

    注2:使用此方法的列表构造不支持所有方法(因为列表由具有固定大小的数组支持)。例如,迭代器的“remove”方法将导致异常。

    严格来说,您无法获得基元数组的迭代器,因为它只能返回一个对象。但是通过自动装箱的魔力,您可以使用该方法获得迭代器

    Iterator it=Arrays.asList(arr.Iterator();
    


    上面的答案是错误的,您不能在基元数组上使用
    数组。asList()
    ,它将返回一个
    列表
    。改为使用的
    Ints.asList()

    如果希望在数组上使用
    迭代器,可以使用其中一个直接实现,而不是将数组包装在
    列表中。例如:

    int[] arr = {1, 2, 3};
    Iterator<Integer> iterator = Arrays.stream(arr).mapToObj(Integer::valueOf).iterator();
    

    或者,这个,如果你想使用泛型:

    请注意,如果您想在基本类型上拥有一个
    迭代器,则不能,因为基本类型不能是泛型参数。例如,如果你想要一个
    迭代器
    ,你必须使用
    迭代器
    ,这将导致大量的自动装箱和-取消装箱,如果这是由
    int[]

    谷歌的集合提供的功能支持的话:

    Iterator<String> it = Iterators.forArray(array);
    
    Iterator it=Iterators.forArray(数组);
    

    人们应该更喜欢Guava而不是Apache集合(它似乎已经被放弃了)。

    我是一名新学生,但我相信int[]的原始示例是迭代原语数组,而不是使用迭代器对象。它只是有相同(相似)的语法和不同的内容

    for (primitive_type : array) { }
    
    for (object_type : iterableObject) { }
    
    Arrays.asList()显然只是将列表方法应用于给定的对象数组,但对于任何其他类型的对象,包括基元数组,iterator()。next()显然只是将原始对象的引用交给您,将其视为一个包含一个元素的列表。我们能看看这个的源代码吗?你不喜欢例外吗?不要介意。我猜(那是猜测)它就像(或它是)一个单身的集合。因此,这里的asList()与基元数组的情况无关,但令人困惑。我不知道我是对的,但我写了一个程序说我是对的

    因此,在这个示例中(基本上asList()并没有做您认为会做的事情,因此您实际上不会使用这种方式)-我希望代码比标记为代码更好,并且,嘿,看看最后一行:

    // Java(TM) SE Runtime Environment (build 1.6.0_19-b04)
    
    import java.util.*;
    
    public class Page0434Ex00Ver07 {
    public static void main(String[] args) {
        int[] ii = new int[4];
        ii[0] = 2;
        ii[1] = 3;
        ii[2] = 5;
        ii[3] = 7;
    
        Arrays.asList(ii);
    
        Iterator ai = Arrays.asList(ii).iterator();
    
        int[] i2 = (int[]) ai.next();
    
        for (int i : i2) {
            System.out.println(i);
        }
    
        System.out.println(Arrays.asList(12345678).iterator().next());
    }
    }
    
    公共类ArrayIterator实现迭代器{
    专用T数组[];
    私人int pos=0;
    公共阵列计数器(T anArray[]{
    数组=数组;
    }
    公共布尔hasNext(){
    返回位置<数组长度;
    }
    public T next()抛出NoTouchElementException{
    if(hasNext())
    返回数组[pos++];
    其他的
    抛出新的NoTouchElementException();
    }
    公共空间删除(){
    抛出新的UnsupportedOperationException();
    }
    }
    
    对于第(2)项,番石榴提供的正是您想要的。关联类中的每个基元类型都有一个等价项,例如,
    Booleans
    对应于
    boolean
    ,等等

        int[] arr={1,2,3};
        for(Integer i : Ints.asList(arr)) {
          System.out.println(i);
        }
    

    我喜欢用番石榴的
    迭代器从第30天得到的答案。然而,在一些框架中,我得到的是null而不是空数组,并且
    迭代器。所以我提出了这个helper方法,您可以使用
    Iterator it=emptyIfNull(array)调用它

    public静态不可修改迭代器emptyIfNull(F[]数组){
    if(数组!=null){
    返回迭代器.forArray(数组);
    }
    返回新的不可修改迭代器(){
    公共布尔hasNext(){
    返回false;
    }
    公共基金下一期(){
    返回null;
    }
    };
    }
    
    在Java 8中:

    Arrays.stream(arr).iterator();
    
    上述每个循环是如何工作的? 与许多其他数组功能一样,JSL明确提到数组并赋予它们神奇的属性:

    [……]

    如果表达式类型是
    Iterable
    的子类型,则翻译如下

    [……]

    否则,表达式必须具有数组类型,
    T[]
    。[[魔法!]]

    L1。。。Lm
    是紧靠增强型for语句前面的标签序列(可能为空)

    增强型for语句相当于以下形式的基本for语句:

    然后:

    main
    me
        int[] arr={1,2,3};
        for(Integer i : Ints.asList(arr)) {
          System.out.println(i);
        }
    
    public static <F> UnmodifiableIterator<F> emptyIfNull(F[] array) {
        if (array != null) {
            return Iterators.forArray(array);
        }
        return new UnmodifiableIterator<F>() {
            public boolean hasNext() {
                return false;
            }
    
            public F next() {
                return null;
            }
        };
    }
    
    Arrays.stream(arr).iterator();
    
    EnhancedForStatement:
    
        for ( FormalParameter : Expression ) Statement
    
    T[] #a = Expression;
    L1: L2: ... Lm:
    for (int #i = 0; #i < #a.length; #i++) {
        VariableModifiersopt TargetType Identifier = #a[#i];
        Statement
    }
    
    public class ArrayForLoop {
        public static void main(String[] args) {
            int[] arr = {1, 2, 3};
            for (int i : arr)
                System.out.println(i);
        }
    }
    
    javac ArrayForLoop.java
    javap -v ArrayForLoop
    
     0: iconst_3
     1: newarray       int
     3: dup
     4: iconst_0
     5: iconst_1
     6: iastore
     7: dup
     8: iconst_1
     9: iconst_2
    10: iastore
    11: dup
    12: iconst_2
    13: iconst_3
    14: iastore
    
    15: astore_1
    16: aload_1
    17: astore_2
    18: aload_2
    19: arraylength
    20: istore_3
    21: iconst_0
    22: istore        4
    
    24: iload         4
    26: iload_3
    27: if_icmpge     50
    30: aload_2
    31: iload         4
    33: iaload
    34: istore        5
    36: getstatic     #2    // Field java/lang/System.out:Ljava/io/PrintStream;
    39: iload         5
    41: invokevirtual #3    // Method java/io/PrintStream.println:(I)V
    44: iinc          4, 1
    47: goto          24
    50: return
    
    int[] arr = {1, 2, 3};
    for (int n : arr) {
        System.out.println(n);
    }
    
    int[] arr = {1, 2, 3};
    
    {  // These extra braces are to limit scope; they do not affect the bytecode
        int[] iter = arr;
        int length = iter.length;
        for (int i = 0; i < length; i++) {
            int n = iter[i];
            System.out.println(n);
        }
    }
    
    public class Arrays {
        public static <T> List<T> asList(T... a) {
            return new ArrayList<>(a);
        }
    
        private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable {
            private final E[] a;
    
            ArrayList(E[] array) {
                a = Objects.requireNonNull(array);
            }
    
            @Override
            public int size() {
                return a.length;
            }
    
            @Override
            public E get(int index) {
                return a[index];
            }
    
            @Override
            public E set(int index, E element) {
                E oldValue = a[index];
                a[index] = element;
                return oldValue;
            }
        }
    }
    
    int[] arr = {1, 2, 3};
    Iterator<Integer> iterator = Arrays.stream(arr).mapToObj(Integer::valueOf).iterator();
    
    int[] arr = {1, 2, 3};
    IntStream stream = Arrays.stream(arr);
    stream.forEach(System.out::println);
    
    int[] arr = {1, 2, 3};
    PrimitiveIterator.OfInt iterator = Arrays.stream(arr);
    
    // You can use it as an Iterator<Integer> without casting:
    Iterator<Integer> example = iterator;
    
    // You can obtain primitives while iterating without ever boxing/unboxing:
    while (iterator.hasNext()) {
        // Would result in boxing + unboxing:
        //int n = iterator.next();
    
        // No boxing/unboxing:
        int n = iterator.nextInt();
    
        System.out.println(n);
    }
    
    final int[] arr = {1, 2, 3};
    Iterator<Integer> iterator = new Iterator<Integer>() {
        int i = 0;
    
        @Override
        public boolean hasNext() {
            return i < arr.length;
        }
    
        @Override
        public Integer next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
    
            return arr[i++];
        }
    };
    
    public final class IntIterator implements Iterator<Integer> {
        private final int[] arr;
        private int i = 0;
    
        public IntIterator(int[] arr) {
            this.arr = arr;
        }
    
        @Override
        public boolean hasNext() {
            return i < arr.length;
        }
    
        @Override
        public Integer next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
    
            return arr[i++];
        }
    }