我是Scala的新手,我想查看String
中是否存在ArrayBuffer[String]
,但不区分大小写。所以我在想创建一个新的类扩展ArrayBuffer[String]
并使用Java String方法equalsIgnoreCase()
例如:
MyArrayBuffer("smallint", "INt", "varchar").contains("int")
班级是这样的:
class MyArrayBuffer[String]() extends ArrayBuffer[String] {
def containsCaseIns(str: String): Boolean = {
for (s <- this) {
if (str.equalsIgnoreCase(s))
true;
}
false;
}
}
但是我因编译错误"value equalsIgnoreCase is not a member of type parameter String"
那我该怎么办呢?或者有更好的方法吗?
答案 0 :(得分:2)
这里使用子类是不必要的。您可以使用现有方法轻松实现此功能
val buff = ArrayBuffer("smallint", "INt", "varchar")
buff.exists(_.equalsIgnoreCase("int")) //true
exists接受一个条件,如果至少有一个元素满足条件,则返回true。
如果您认为添加方法更好[&34; containsIgnoreCase&#34;对于ArrayBuffer [String],你可以很容易地做到这一点,而无需使用扩展方法进行子类化,有时也称为&#34;增强我的库&#34;图案。您可以实现这一点,即将方法添加到隐式类中。
object Extensions {
implicit class EnhancedStringBuffer(val underlying: ArrayBuffer[String]) extends AnyVal {
def containsIgnoreCase(elem: String): Boolean = underlying.exists(_.equalsIgnoreCase(elem))
}
}
现在可行了
import Extensions._
ArrayBuffer("smallint", "INt", "varchar").containsIgnoreCase("int") //true
因为它是一种值类型,所以不会产生任何额外的运行时对象分配成本。您甚至可以使它更通用,使用GenTraversableOnce[String]
作为底层类型,然后您可以将此新方法用于任何字符串集合。
请注意,这些方法以O(n)时间复杂度运行(一旦找到匹配就存在短路,因此它不总是需要完全遍历)。如果要收集大量字符串,并且需要经常进行包含检查,则可能需要完全采用不同的方法。在这种情况下,您在输入时将所有条目转换为大写的哈希集可能是您最好的选择。
import scala.collection.mutable
class CaseInsensitiveStrings {
private[this] val strings = new mutable.HashSet[String]()
def addString(elem: String) = strings.add(elem.toUpperCase)
def contains(elem: String) = strings.contains(elem.toUpperCase)
}
如果你只有一个相对较小的字符串集,或者你不经常这样做包含检查,这可能不值得做,但如果是这样的话,一个hashset将允许有效查找甚至大套的字符串。这意味着您不能存储相同的不区分大小写的字符串的倍数,因此如果您需要,您可以稍微改变一下。您可以添加您认为必要的任何其他方法或特征,但要小心确保所有条目都是大写的不变量。
答案 1 :(得分:1)
有关您的类无法编译的原因的一些背景信息:
您的类定义了一个名为String
的类型参数,该参数隐藏了类java.lang.String
。
如果您将其编写为
,您的课程将编译class MyArrayBuffer() extends ArrayBuffer[String] {
def containsCaseIns(str: String): Boolean = {
for (s <- this) {
if (str.equalsIgnoreCase(s))
true;
}
false;
}
}
答案 2 :(得分:0)
这将起作用(a是你的缓冲区):
a.filter(_.equalsIgnoreCase("int")).length > 0