我刚刚偶然发现了托尼·莫里斯的一张关于 Java 的博客文章该语言的一个基本问题是:为集合定义定制的相等关系。我认为这是一个big deal并想知道是否有一些 scala 解决方案。
这个经典问题体现在对交易的思考中。假设我以 150p 的价格进行了两次 +100 股沃达丰股票的交易。两笔交易是平等的,是吗?但他们不是同一行业。对于正常的现实系统,具有持久性或序列化,我不能依赖identity告诉我两个参考文献是否是同一行业!
所以我想要的是能够创建一个集合,我可以将相等关系传递给:
val as = CleverSet[Trade](IdEquality)
val bs = CleverSet[Trade](EconomicsEquality)
我将如何以有效的方式实现我的集合(除非EqualityRelation
还定义了一个hash
机制)?
trait EqualityRelation[T] {
def equal(t1: T, t2: T) : Boolean
def hash(t: T) : Int
}
所以问题是:
- 有没有提供这种能力的库?
- Scala 有什么方法可以巧妙地做到这一点吗?
看起来,使用隐式,添加到现有的 scala 中将是一件很容易的事情Set
type.
这已经可以通过 Java 的 TreeSet 和 Comparator 实现来实现:
TreeSet<String> ignoreCase = new TreeSet<String>(new Comparator<String>(){
@Override
public int compare(String o1, String o2) {
return o1.compareToIgnoreCase(o2);
}});
TreeSet<String> withCase = new TreeSet<String>();
List<String> values = asList("A", "a");
ignoreCase.addAll(values);
withCase.addAll(values);
Output:
ignoreCase -> [A]
withCase -> [A, a]
这样做的缺点是要实现的比较器比所需的功能更强大,并且您仅限于支持比较器的集合。正如 oxbow_lakes 所指出的,Comparator 的实现破坏了 Set 契约(对于!a.equals(b)
可能是这样new Set(); set.add(a) == true && set.add(b) == false
).
Scala 通过 A => Ordered[A] 的视图转换来支持这一点。
scala> new scala.collection.immutable.TreeSet[String]()(x=> x.toLowerCase) + "a"
+ "A"
res0: scala.collection.immutable.TreeSet[String] = Set(A)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)