斯卡拉的平等关系 [英] Equality relations in Scala

查看:86
本文介绍了斯卡拉的平等关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我偶然发现了Tony Morris的博客有关Java的帖子和该语言的一个基本问题:为集合定义定制的平等关系。我认为这是一件大事,想知道是否存在一些scala解决方案。

I just stumbled on one of Tony Morris' blog-posts about Java and a fundamental problem with the language: that of defining a bespoke equality-relation for a collection. This is something that I think is a big deal and wondered whether there was some scala solution.

经典问题体现在考虑交易等方面。假设我以150p的价格交易了两笔100股沃达丰股票。这两个行业是平等的,是吗?除非它们不是同一行业。对于具有持久性或序列化功能的常规真实系统,我不能依靠 identity 来告诉我两个引用是否指向同一交易!

The classic issue manifests itself in thinking about, say, a trade. Let's say I make two trades of +100 vodafone shares @150p. The two trades are equal, yes? Except they are not the same trade. In the case of a normal real-world system, with persistence or serialization, I cannot rely on identity to tell me whether two references are to the same trade!

所以我想要的是能够创建一个集合,我可以将一个平等关系传递给:

So what I want is to be able to create a collection which I can pass an Equality-relation to:

val as = CleverSet[Trade](IdEquality)
val bs = CleverSet[Trade](EconomicsEquality)

如何我是否可以高效地实现我的集合(除非 EqualityRelation 也定义了 hash 机制)?

How would I implement my set in an efficient manner (unless the EqualityRelation also defines a hash mechanism)?

trait EqualityRelation[T] {
  def equal(t1: T, t2: T) : Boolean
  def hash(t: T) : Int
}

所以问题是:


  • 是否有一个提供此功能的库?

  • 在Scala中有某种方法可以很好地做到这一点吗?

使用隐式函数,将它添加到现有的scala Set

It seems that with implicits, it would be quite an easy thing to add to the existing scala Set type.

推荐答案

这可以通过Java的TreeSet和Comparator实现来实现:

This can already be achieved with Java's TreeSet and a Comparator implementation:

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);

输出:

ignoreCase -> [A]
withCase -> [A, a]

这样做的缺点是比较器实现的功能比所需的功能强大,并且您只能使用支持比较器的集合。如oxbow_lakes所指出的,Comparator实现破坏了Set合同(对于!a.equals(b)可能是 new Set(); set .add(a)== true&& set.add(b)== false )。

This has the drawbacks that the Comparator to implement is more powerful than needed and that you're restricted to collections that support Comparators. As pointed out by oxbow_lakes the Comparator implementation breaks the Set contract (for !a.equals(b) it could be that new Set(); set.add(a) == true && set.add(b) == false).

Scala支持使用

scala> new scala.collection.immutable.TreeSet[String]()(x=> x.toLowerCase) + "a"
 + "A"
res0: scala.collection.immutable.TreeSet[String] = Set(A)

这篇关于斯卡拉的平等关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆