在整个 Google Guava 库中,我注意到使用“一个(或两个)加 var args”技术的趋势。
例子:
void add(T value, T... moreValueArr) void add(T value, T value2, T... moreValueArr) 我花了一段时间才弄清楚原因:为了防止使用零个参数(在第一种情况下)或一个参数(在第二种情况下)进行调用。
进一步扩展此技术,如果在下面的场景 A 和 B 之间进行选择,哪个更可取?我希望具有深厚 Java 知识的人可以提供见解。
场景A:(两种方法)
void add(T... valueArr) void add(Iterable<? extends T> iterable) 场景B:(三种方法)
void add(T value, T... moreValueArr) void add(T[] valueArr) void add(Iterable<? extends T> iterable) 为什么 B 可能更好的一个想法:我注意到许多 Java 程序员不知道数组可以作为 var args 直接传递。因此,B 可能会提供关于什么是可能的提示。
最后,我意识到 B 有额外的开发、测试和维护开销。请将这些考虑放在一边。
这个问题是我原来问题的细微变化:Java varags method param list vs. array
最佳答案
最后会得出结论。如果您只想要结论,请跳到最后。
主要目标是性能。
如果有很多只传递 1 或 2 个元素的用例,您可以避免创建数组。是的,仍然有一个零长度数组将被传递,但由于无法修改零长度数组,因此允许 JVM 传递一个共享实例,例如,如果缓存,则根本不会影响性能。
这方面最出色的例子是 EnumSet.of() 方法(它返回列出的枚举实例的 EnumSet)。
您将看到以下重载:
static <E extends Enum<E>> EnumSet<E> of(E e);
static <E extends Enum<E>> EnumSet<E> of(E first, E... rest);
static <E extends Enum<E>> EnumSet<E> of(E e1, E e2);
static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3);
static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4);
static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4, E e5);
如果您使用 5 个或更少的元素调用 of() 方法,将不会创建数组,因为存在可以采用 5 个或更少元素的重载。 EnumSet.of(E first, E... rest) 的 javadoc 中也提到了性能
This factory, whose parameter list uses the varargs feature, may be used to create an enum set initially containing an arbitrary number of elements, but it is likely to run slower than the overloadings that do not use varargs.
至于为什么要使用of(E first, E... rest)即使有单独的of(E e1, E e2) :
这只是为了方便实现。如果您声明了一个first 参数,您就可以使用它而不必检查数组的长度或不必使用索引。例如,您可以使用它来检查其类型(这在使用泛型时通常很重要)。
它并没有真正强制传递至少一个参数,因为如果只有 vararg 参数,您可以像传递一个空数组一样轻松地传递一个 null。
可变参数与数组
如果数组的类型不是原始类型,则没有真正的区别,除了数组参数强制您显式创建数组,而 vararg 参数允许您传递数组或仅列出元素。
尽管有数组参数的历史原因(varargs 仅在 Java 5.0 中加入),但仍有一些地方必须使用数组:
可迭代参数
Iterable 在这种情况下是将多个值传递给方法的替代方法,但它不能替代数组和可变参数。 Iterable 用于集合,因为如果参数是 Iterable(数组不实现 Iterable),则不能使用数组或列出元素。如果调用者有集合形式的输入数据(例如List或Set),Iterable参数是最方便的,传递元素的最通用和最有效的方法。
得出结论
回到您最初的场景 A 和 B。由于您的两个场景都包含带有 Iterable 参数的方法,并且由于 Iterable 不与数组“混合”,我通过省略这些来减少问题:
场景A:(一种方法)
void add(T... valueArr)场景B:(两种方法)
void add(T value, T... moreValueArr)void add(T[] valueArr)由于方法 add() 只从数组中读取(而不是写入数组;从名称 add 假设),每个用例都可以用两者来解决他们中的。为简单起见,我会选择方案 A。
关于Java 方法参数 : var args vs array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25217815/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun