我一直想知道在最佳实践中是否允许不使用该containsKey()方法java.util.Map,而是对结果进行空检查get().
我的理由是,对值进行两次查找似乎是多余的 - 首先是for containsKey(),然后是for get().
另一方面,可能是大多数标准实现的Map高速缓存是最后一次查找,或者编译器可以以其他方式取消冗余,并且为了代码的可读性,优选维护该containsKey()部分.
我非常感谢你的评论.
我委托了几种方法,并希望它们都是私有的.
class Walrus
delegate :+, :to => :bubbles
def bubbles
0
end
end
Run Code Online (Sandbox Code Playgroud)
我可以说private :+,但我必须为每种方法做到这一点.有没有办法返回委托方法列表或委托创建私有方法?
我用Java开发了很多代码,并涉足Groovy和Haskell,现在我已经把我带到了Scala.
我对Scala的功能方面感到相对舒服,但我发现自己在Scala中的面向对象设计上有些不稳定,因为它感觉与Java有点不同,特别是由于特性/混合.
我的目标是编写尽可能可测试的代码,这在我的Java开发中一直都是关注的
现在我正试图在这个新的Scala领域站起来,我很难弄清楚我应该采取什么方法,特别是我是否应该为某些目的开始使用继承.
编程Scala(Wampler和Payne; O'Reilly,第2版)有一个考虑因素("良好的面向对象设计:一个题外话"),我已经阅读了很多关于SO的帖子,但我还没有看到明确提到可测试性的设计考虑因素.本书提供了有关使用继承的建议:
- 抽象基类或特征由具体类(包括案例类)分为一级.
- 除了两种情况外,具体类永远不会被子类化:
- 混合在特征中定义的其他行为的类(...)
- 仅测试版本,以促进自动化单元投影.
- 当子类化似乎是正确的方法时,考虑将行为划分为特征并改为混合这些特征.
- 永远不要跨父子类型边界拆分逻辑状态.
对SO的一些挖掘也表明,有时混合比组合更好.
所以本质上我有两个问题:
是否有一些常见的情况,即使考虑可测试性,使用继承会更好?
混合是否提供了增强代码可测试性的好方法?
我需要浅浅地复制Groovy映射中的所有条目,除了一个,我已经知道了密钥.我更喜欢不可变和简洁的方法,并且该minus()方法非常合适,除了提供密钥是不够的,我必须做这样的事情:
def map = [a:"aa", b:"bb"]
def knownKey = "a"
def result = map - [(knownKey):map[knownKey]]
assert result == [b:"bb"]
Run Code Online (Sandbox Code Playgroud)
或者,我可以放弃(暂时)不变性并remove()使用键作为参数调用该方法.
我可以采取一种常规方法吗?
在我的 Sidekiq Pro 设置中,我有大约 10 个不同权重的队列。我的目的是使用权重来指示队列的优先级。
前几天我遇到了一个事件,导致一批低权重作业产生大量,并且似乎对高权重作业也存在竞争效应。
在文档的这一部分中,我阅读了以下内容:
每个队列都可以配置一个可选的权重。权重为 2 的队列的检查频率是权重为 1 的队列的两倍
这让我有点困惑。我可以期望权重产生优先级队列语义吗?
我在玩一些Ruby中浮点舍入错误的玩具示例,并且发现以下行为令我感到惊讶。
首先,一个不奇怪的例子,其中发生舍入错误:
numbers = Array.new(10, 0.1)
#=> [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
numbers.inject(0, :+)
#=> 0.9999999999999999
Run Code Online (Sandbox Code Playgroud)
现在尝试使用Enumerable#sum:
numbers.sum
#=> 1.0
Run Code Online (Sandbox Code Playgroud)
我在文档中唯一可以找到解释的提示是
sum方法可能不遵守“ +”方法(例如Integer#+)的方法重新定义。
因此我想有某种本机代码实现可以加快速度,但是我认为C浮点也受IEEE-754相关的不精确算法的影响。
在第二个示例中出现此行为的原因是什么?该sum方法如何避免舍入误差?
我需要在多线程环境中在Scala中缓存一些东西.
阅读scalaz,Memo我在不可变哈希映射备忘录的代码中找到了以下注释:
由于此备忘录使用单个var,因此它是线程安全的.
代码如下所示:
def immutableMapMemo[K, V](m: Map[K, V]): Memo[K, V] = {
var a = m
memo[K, V](f =>
k => {
a get k getOrElse {
val v = f(k)
a = a updated (k, v)
v
}
})
}
Run Code Online (Sandbox Code Playgroud)
说这是线程安全的,与我到目前为止所阅读和学到的关于JVM平台上的线程安全的内容相反; 参考更新可能是原子的,但正如我所理解的那样,如果您没有内存屏障,编译器可能会尝试进行某些优化来扰乱发生在之前的关系.例如,请参阅此帖和此内容.
但我确信那些scalaz人非常聪明.也许有关于范围的特别之处a.
评论声称是真的,如果是,为什么?
在JDK文档中,它声明String方法isEmpty()对于任何长度为0 的字符串都是true.
对于空字符串来说,这显然是正确的"".
是否还有其他字符串?我测试过换行符和回车符,它们有一个长度.我还没有测试带有附加退格的字符.
编辑:我很欣赏以下所有好答案中的所有其他信息,但我已经接受了我认为最直接的答案.
java ×3
map ×2
ruby ×2
scala ×2
algorithm ×1
delegates ×1
enumerable ×1
groovy ×1
hashmap ×1
ieee-754 ×1
is-empty ×1
memoization ×1
oop ×1
performance ×1
scalaz ×1
sidekiq ×1
string ×1
testability ×1
unit-testing ×1