Java for-each循环

常见循环

java目前常见的循环主要有3种:

1.iterator循环

        List<Integer> list = new ArrayList<Integer>();
        for (Iterator iterator = list.iterator(); iterator.hasNext(); ) {
            System.out.println(iterator.next());
        }

2.下标循环

        Integer[] list = new Integer[10];
        for (int i = 0, size = list.length; i < size; i++) {
            System.out.println(list[i]);
        }

3.for-each循环

        List<Integer> list = new ArrayList<Integer>();
        for (Integer i : list) {
            System.out.println(i);
        }

for-each循环比较

  1. for-each循环优势
    for-each循环不会有性能的损耗,下标循环是最快的了,for-each和它相比,性能基本差距不大,可以忽略。
    for-each循环再面对多重循环时,不存在下标问题等,易于使用。例如,2重3重循环,存在很多变量。
  2. for-each循环使用
    一般的集合、数组都可以使用for-each进行循环,同时我们也可以继承Iterable接口,实现for-each循环。只要实现了这个接口,就可以使用for-each循环了。
    一下是jdk8的Iterator api:
/**
 * Implementing this interface allows an object to be the target of
 * the "for-each loop" statement. See
 */
public interface Iterable<T> {
    /**
     * Returns an iterator over elements of type {@code T}.
     */
    Iterator<T> iterator();

    /**
     * Performs the given action for each element of the {@code Iterable}
     * until all elements have been processed or the action throws an
     * exception.  Unless otherwise specified by the implementing class,
     * actions are performed in the order of iteration (if an iteration order
     * is specified).  Exceptions thrown by the action are relayed to the
     * caller.
     *
     * @implSpec
     * <p>The default implementation behaves as if:
     * <pre>{@code
     *     for (T t : this)
     *         action.accept(t);
     * }</pre>
     *
     * @param action The action to be performed for each element
     * @throws NullPointerException if the specified action is null
     * @since 1.8
     */
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

    /**
     * Creates a {@link Spliterator} over the elements described by this
     * {@code Iterable}.
     *
     * @implSpec
     * The default implementation creates an
     * <em><a href="Spliterator.html#binding">early-binding</a></em>
     * spliterator from the iterable's {@code Iterator}.  The spliterator
     * inherits the <em>fail-fast</em> properties of the iterable's iterator.
     *
     * @implNote
     * The default implementation should usually be overridden.  The
     * spliterator returned by the default implementation has poor splitting
     * capabilities, is unsized, and does not report any spliterator
     * characteristics. Implementing classes can nearly always provide a
     * better implementation.
     *
     * @return a {@code Spliterator} over the elements described by this
     * {@code Iterable}.
     * @since 1.8
     */
    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}

注意点

以下出现的情况,不要使用for-each

  1. 过滤–当遍历时,需要删除元素,需要使用显示的迭代器,以便调用remove方法,推荐使用Iterator方法,安全没问题。当使用下标循环去remove集合时,容易造成下表位置移动,remove错。
  2. 转换
  3. 平行迭代

一般情况下,推荐使用for-each

快捷使用

当查找某个元素时,一般都是采用集合的contain()方法判断的,或者快捷的for循环进行判断。
一般的快速for判断

        int[] list = new int[]{1, 5, 3, 7, 9, 2};
        int m = 3;
        boolean isContain = false;
        for (int i = 0; i < list.length; i++) {
            if (list[i] == m) {
                isContain = true;
                break;
            }
        }
        System.out.println(isContain);

对于这种判断一般采用其他帮助类更好,如下:

        System.out.println(ArrayUtils.contains(list, 3));

其中ArrayUtils的源码如下,更严谨:

    public static boolean contains(int[] array, int valueToFind) {
        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
    }

    public static int indexOf(int[] array, int valueToFind) {
        return indexOf(array, valueToFind, 0);
    }

    //int[]
    public static int indexOf(int[] array, int valueToFind, int startIndex) {
        if (array == null) {
            return INDEX_NOT_FOUND;
        }
        if (startIndex < 0) {
            startIndex = 0;
        }
        for (int i = startIndex; i < array.length; i++) {
            if (valueToFind == array[i]) {
                return i;
            }
        }
        return INDEX_NOT_FOUND;
    }

    //Object
    public static int indexOf(Object[] array, Object objectToFind, int startIndex) {
        if (array == null) {
            return INDEX_NOT_FOUND;
        }
        if (startIndex < 0) {
            startIndex = 0;
        }
        if (objectToFind == null) {
            for (int i = startIndex; i < array.length; i++) {
                if (array[i] == null) {
                    return i;
                }
            }
        } else if (array.getClass().getComponentType().isInstance(objectToFind)) {
            for (int i = startIndex; i < array.length; i++) {
                if (objectToFind.equals(array[i])) {
                    return i;
                }
            }
        }
        return INDEX_NOT_FOUND;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值