java+list可变参数_高效Java第四十二条慎用可变参数

原标题:高效Java第四十二条慎用可变参数

概念

JDK5增加了可变参数方法(variable arity method)

可变参数方法接受0个或多个指定类型的参数。

可变参数机制:先创建一个数组,数组大小为调用位置所传递的参数数量,然后将参数值传递到数组中,最后将数组传递给方法。

de4753e06e95a452e7544d3d1bc11322.png 问题的提出

编写需要一个或多个某种类型参数的方法,而不是需要零个或多个参数。例如求多个int参数的最小值。可变参数方法不适合这种场景。

27084d953ca08a92c0724c63bc7d4b40.png

问题:如果客户端调用这个方式时,没有传递参数,会在运行时而不是编译时失败;代码不美观。必须对args进行显示的有效性检查,除非将min初始化为Integer.MAX_VALUE,否则无法使用for-each循环。 问题的解决办法

声明该方法带有两个参数,一个是指定类型的正常参数,另一个是这种类型的varargs参数。

f838d4f142a82bfaa69c46af89b8c106.png 可变参数的适用场景

当真正需要一个方法带有不定数量的参数时,可变参数就非常有效。

可变参数是为printf而设计的,它是在jdk5引入的。

printf和反射机制都从可变参数中获得极大的收益。 错误的例子 Arrays.asList增强为可使用可变参数

可以将以final数组作为参数的方法,改造成可变参数版本。但是不应该这么做。

Arrays.asList方法不是设计用来将多个参数集中到一个列表中的。

5ad044cf28eba64362da8379a922cac6.png

上面打印数组内容的方法只在对象引用类型的数组上才有用。

在JDK5之前,Arrays.asList()在基本类型的数组上用将无法编译。

86bcfff246118250cf86ba7b4f393b18.png

现在的版本呢?

ec552ab19b12e3655cfc2a3ec3406f68.png

通过对比,可以发现,传入基本数据类型的数组也是可以通过编译的,但是运行这个程序,会输出无意义的结果。

Arrays.asList方法将int类型的数组的引用集中到单个元素数组中,并封装成List。

4cb92715a3e8060d3b92970f38c0a0bf.png

将数组转变为字符串的Arrays.asList已经过时了。Arrays类有专门将任何类型的数组转变为字符串的方法。 //The right way to print an arraySystem.out.println(Arrays.toString(digits));

如果不改造Arrays.asList,更好的办法是给Collections添加一个新的方法,专门用来将它的参数集中到列表中。

5b04cfbc74ad89ae6cf9db2460573dc2.png

这种方法可以提供收集功能,而不会危及对现有Arrays.asList方法的类型检查。

不必改造具有final数组参数的每个方法;只当确实是在数量不定的值上执行调用时才使用可变参数。

7db5737b20293986b75b81920a3470fc.png 可变参数的性能问题

每次调用可变参数方法都会进行一次数组分配和初始化。 解决办法——重载:

假设确定对某个方法95%的调用会有3个或者更少的参数,就声明该方法的5个重载,每个重载方法带有0至3个普通参数,当参数的数目超过3个时,就使用一个可变参数方法。

b7983856bed0f86b7a254fe0c0d7c07d.png

所有的调用只有5%参数数量超过3个的调用需要创建数组。

965c6f33bb6919fc7c6da4206b40d4e8.png

EnumSet类对它的静态工厂使用了这种方法,最大限度地减少创建枚举集合的成本,枚举集合为位域提供在性能方面有竞争性的代替方法。

西安Java培训0学费+0基础+项目实战演练+大咖讲师=高薪就业,150天让你从菜鸟变大咖。

责任编辑:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值