Java for each

在学习《Java  核心技术》时,在一个例程的实现过程中,我发现两处对数组的操作(赋值、历遍)使用了不同的for循环体。

本来以为是原作者希望以多种的代码实现方式来丰富学习者的经验,于是我便将两个循环都改成了for each。

然而,IDE显示变量并没有被使用,程序与运行的结果也不正常。

我开始怀疑for each的实现方式。

google发现,for each 的方式只用于读取、历遍,不能用于赋值。

代码如下:

正确:

 for (int i = 0; i < values.length; i++) 
            values[i] = 100 * Math.random();

错误:

 for (double v : values)
            v = 100 * Math.random();


那么为什么会出现这样的结果呢?

其实问题很简单,从for each的代码书写形式规范上就能推断一二。

 for (double v : values)

可以试着把for理解为一种特殊函数,for的循环体就可以理解问函数体。

循环中的v,是一个变量名,可以这么理解成一个传给for函数的参数。本例中v作为函数参数在for函数体中被更新、修改。

然而,依据函数参数的定义,传给函数的只是一个拷贝副本,与调用函数时的参数在内存地址上并不同,只是内容数值相同。

那么,具体到本例:

 for (double v : values)
            v = 100 * Math.random();
v只是一个values这个数组中某一个元素的拷贝,更新v的值并不能影响到values这个数组本身,二者在内存中的地址是完全不同的。


for (int i = 0; i < values.length; i++) 
            values[i] = 100 * Math.random();
这种循环我们可以理解为传递给for函数的是数组的指针、偏移地址。

通过对指针指向的对象的操作,我们直接访问了values数组的内存地址,更新、修改的是对应的地址单元中的内容。


上面关于for循环的函数比喻可能不是很恰当,仅仅为了能更好理解我们的问题。

以下是原例程代码:

/**
 * Created at 2015/6/14.
 * desc: This program demonstrate the use of static inner classes
 *
 * @author Magy
 * @version 1.0
 */
public class StaticInnerClass {
    private static final String TAG = "StaticInnerClass";

    public static void main(String[] args) {
        double[] values = new double[20];
        for (int i = 0; i < values.length; i++) {
            values[i] = 100 * Math.random();
        }
        for (double v : values)
            v = 100 * Math.random();
        ArrayAlg.Pair p =  ArrayAlg.minmax(values);
        System.out.println("min = " + p.getFirst());
        System.out.println("max = " + p.getSecond());
    }
}

class ArrayAlg{
    /**
     * A pair of floating_point numbers
     */

    public static class Pair{
        private double first;
        private double second;

        /**
         * Constructs a pair from twe floating-point numbers
         * @param first the first number
         * @param second the second number
         */
        public Pair(double first, double second) {
            this.first = first;
            this.second = second;
        }

        /**
         * Return the first number of the pair
         * @return the the first number
         */
        public double getFirst() {
            return first;
        }

        /**
         * Return the second number of the pair
         * @return the second number
         */
        public double getSecond() {
            return second;
        }
    }

    /**
     * Computes both the minimum and the maximum of an array
     * @param values an array of floating-point numbers
     * @return a pair whose first element is the minimum and whose second element is the minimum
     */
    public static Pair minmax(double[] values){
        double min = Double.MAX_VALUE;
        double max = Double.MIN_VALUE;
        for (double v : values){
            if (min > v)    min = v;
            if (max < v)    max = v;
        }
        return new Pair(min, max);
    }
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值