EffectiveJava学习笔记25:通用编程(上)-局部变量的作用域最小化、for-each和for、类库和random三种随机

1.将局部变量的作用域最小化

就是将局部变量影响的范围尽量最小化,已避免影响其他的方法。

其将局部变量影响的作用域最小化的设计原则:

1.在第一次要使用局部变量的地方进行声明

2.大多的局部变量声明时都应该包含一个初始化表达式

3.局部变量所在的方法应该小且集中。

4.循环变量(for或for-each中的变量)作用域被自动限定在正好需要的范围内:循环体、循环体之前的初始化、测试、更新。(所以for循环优于while循环)

 

2.for-each循环优于传统的for循环

书中是这样讲的:与for循环相比,for-each循环在简洁灵活性和出错预防性方面占优势,且没有性能惩罚的问题。所以可以选择时,for-each应该优先于for循环。

但是我感觉需要看要如何使用,再决定用for-each还是for。

在我看来foreach有个缺点,就是不支持在循环中添加删除操作,一旦开始循环,它循环列表就固定下来了,即使循环中删除了中间某个循环对象,它仍然会循环这个已删除的循环对象。而for可以。

举例:

for循环:

    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("沙");
        list.add("丁");
        list.add("鱼");
        list.add("flat");;
        System.out.println("原有:"+list.toString());
        for (int i = 0; i <list.size(); i++) {
            list.remove("flat");
        }
        System.out.println("删除后:"+list.toString());
    }

 

for-each循环:

出错了,表明在循环时提前删除某个循环点的数据,它并不会自动跳过。

当然有人会想:那我当循环到那个点时再删除,就不会报错了呀,但这是错的,请看下面一个例子:

 

总结一下

for-each的缺点:

1.for-each不适合用于集合在循环中会删除元素的。(书中叫:结构过滤)

2.for-each不适合在循环中修改元素,取代元素(书中叫:转换) (PS:如果循环的是类实例集合,那么修改类实例中的变量子类的是可以的,但不能修改整个类实例的对象)

3.for-each 不适合用于并行地遍历多个集合的情况(书中叫:平行迭代)

以上3种情况,for循环更加好

 

for-each的优点:

1.在循环外就已删除某个集合节点的元素的话,可以自动跳过已删除的元素(for需要检测自写)

2.无需写迭代器或者索引变量,直接隐藏了,更简洁明了。

 

 

3.了解和使用类库

这一节内容主要是建议我们跟随时代潮流,多看新版本JDK中的标准类库的内容,特别是新加的特性功能。

建议熟悉java.lang、java.util、java.io 及其子包中的内容

这里就写点java的random用法,没看这内容前,我还真不知道java自身也有random,是我太渣o(╥﹏╥)o。

现在java有三种随机数

第一种:java.lang.Math.Random

这种也是最常见的Random,其作用是:返回一个正的double值,范围是[0.0, 1.0),在该范围内近似是均匀分布

    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            System.out.println("随机值第"+(i+1)+"次:"+(int)(Math.random()*10));
        }
    }

 

第二种:java.util.Random

它的特点是有个随机种子

它实现的随机算法是伪随机(有规则的随机)。

PS:它实际上生成的随机数字都是均匀分布的,也就是说区间内部的数字生成的几率均等。

PS:在给定种(seed)的区间内随机生成数字,所以相同种子数的Random对象,相同次数生成的随机数字是完全相同的;

 

然后我发现一件事,那就是math.Random是用的util.Random做的,从random()方法逐级进去

由此也可以看出

util.Random的构造函数实际上有两个,一个是Random(),以当前时间为默认种子,进行伪随机计算。

另一个Random(long seed)。第二个是以指定的种子值进行。

举例:

    public static void main(String[] args) {
        Random random=new Random(1);
        for(int i=0;i<10;i++){
            //System.out.println("随机值第"+(i+1)+"次:"+(int)(Math.random()*10));
            System.out.println("随机值第"+(i+1)+"次:"+(int)(random.nextInt(10)));
        }
    }

util.Random缺点,由于种子值固定,它随机出来的数也是固定的,我执行了3次这串代码,但结果都是一样。

上面的math.random由于是种子值是时间,所以在变化的,所以随机出来的数是随着时间在变的,

当然这也暴露出math.random的一个缺点:math.random随机间隔时间过小,那么随机出来的数也是固定的。

 

第二种:java.util.concurrent.ThreadLocalRandom

ThreadLocalRandom是Random的加强版,他是Random的子类

它的优点是:在并发访问的情况下,使用ThreadLocalRandom代替Random,可以减少线程间的资源竞争,从而保证系统具有更好的线程安全。

具体举例:

    public static void main(String[] args) {
        Random random=new Random(2);
        ThreadLocalRandom rand=ThreadLocalRandom.current();

        for(int i=0;i<10;i++){
            //System.out.println("随机值第"+(i+1)+"次:"+(int)(Math.random()*10));
            //System.out.println("随机值第"+(i+1)+"次:"+(int)(random.nextInt(11)));
            System.out.println("随机值第"+(i+1)+"次:"+(int)(rand.nextInt(10)));
        }
    }

这里注意!!!!! ThreadLocalRandom和Random不一样,它每次随机的数字不一样。它也会自动生成种子

所以可以说使用ThreadLocalRandom比Random更高效,而且更加安全。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值