番石榴多集和餐桌概念是否有scala替代品?

番石榴多集和餐桌概念是否有scala替代品?,scala,guava,scala-collections,Scala,Guava,Scala Collections,要在scala中使用番石榴表和多集?scala中是否已经存在不同的concenpts而不是导入番石榴库以用于此用途?您可以使用Map[(R,C),V]而不是Table和Map[T,Int]而不是Multiset。您还可以向Map[T,Int]添加助手方法,如下所示: implicit class Multiset[T](val m: Map[T, Int]) extends AnyVal { def setAdd(e: T, i: Int = 1) = { val cnt = m.g

要在scala中使用番石榴
多集
?scala中是否已经存在不同的concenpts而不是导入番石榴库以用于此用途?

您可以使用
Map[(R,C),V]
而不是
Table
Map[T,Int]
而不是
Multiset
。您还可以向
Map[T,Int]
添加助手方法,如下所示:

implicit class Multiset[T](val m: Map[T, Int]) extends AnyVal {
  def setAdd(e: T, i: Int = 1) = {
    val cnt = m.getOrElse(e, 0) + i
    if (cnt <= 0) m - e
    else m.updated(e, cnt)
  }
  def setRemove(e: T, i: Int = 1) = setAdd(e, -i)
  def count(e: T) = m.getOrElse(e, 0)
}

val m = Map('a -> 5)

m setAdd 'a
// Map('a -> 6)

m setAdd 'b
// Map('a -> 5, 'b -> 1)

m setAdd ('b, 10)
// Map('a -> 5, 'b -> 10)

m setRemove 'a
// Map('a -> 4)

m setRemove ('a, 6)
// Map()

m count 'b
// 0

(m setAdd 'a) count 'a
// 6
隐式类Multiset[T](val m:Map[T,Int])扩展了AnyVal{
def setAdd(e:T,i:Int=1)={
val cnt=m.getOrElse(e,0)+i
如果(cnt 1)
m setAdd('b,10)
//地图('a->5,'b->10)
m setRemove'a
//地图('a->4)
m setRemove('a,6)
//地图()
我是b伯爵
// 0
(m设置添加“a”计数“a”
// 6

这是第一个使用
Map[(R,C),V]
作为委托集合的简单实现。
用作
m:Map
的索引

package utils.collections

import utils.collections.Table.Cell

class Table[R, C, V](val m: Map[(R, C), V], val rows: Map[R, List[(R, C)]], val columns: Map[C, List[(R, C)]]) {

  def containsValue(value: V): Boolean = m.values.exists(_.equals(value))

  def values(): List[V] = m.values.toList

  def get(rowKey: R, columnKey: C): Option[V] = m.get(rowKey, columnKey)

  def apply(rowKey: R, columnKey: C): V = m.apply((rowKey, columnKey))

  def cellSet(): Set[Cell[R, C, V]] = m.map { case ((r, c), v) => Cell(r, c, v) }.toSet

  def contains(rowKey: R, columnKey: C): Boolean = m.contains((rowKey, columnKey))

  def put(rowKey: R, columnKey: C, value: V): Table[R, C, V] = {
    val keys: (R, C) = (rowKey, columnKey)
    new Table(
      m = m + ((keys, value)),
      rows = rows + ((rowKey, keys::rows.getOrElse(rowKey, List.empty))),
      columns = columns + ((columnKey, keys::columns.getOrElse(columnKey, List.empty)))
    )
  }

  def putAll(table: Table[_ <: R, _ <: C, _ <: V]): Table[R, C, V] = Table(m.++(xs = table.m))

  def remove(rowKey: R, columnKey: C): Table[R, C, V] = {
    val keys: (R, C) = (rowKey, columnKey)
    val updatedRows: Map[R, List[(R, C)]] = rows.get(rowKey) match {
      case Some(keysWithRow) if keysWithRow.diff(List(keys)).nonEmpty => rows + ((rowKey, keysWithRow.diff(List(keys))))
      case _ => rows - rowKey
    }
    val updatedColumns: Map[C, List[(R, C)]] = columns.get(columnKey) match {
      case Some(keysWithColumn) if keysWithColumn.diff(List(keys)).nonEmpty => columns + ((columnKey, keysWithColumn.diff(List(keys))))
      case _ => columns - columnKey
    }
    new Table(
      m = m - keys,
      rows = updatedRows,
      columns = updatedColumns
    )
  }

  def row(rowKey: R): Map[C, V] = m.filterKeys(k => rows.get(rowKey).exists(_.equals(k))).map { case ((_, c), v) => (c, v) }

  def containsRow(rowKey: R): Boolean = rows.exists(_.equals(rowKey))

  def rowMap(): Map[R, Map[C, V]] = m.groupBy { case ((r, _), _) => r }.map { case (r, subMap) => (r, subMap.map { case ((_, c), v) => (c, v) }) }

  def rowKeySet(): Set[R] = rows.keySet

  def column(columnKey: C): Map[R, V] = m.filterKeys(k => columns.get(columnKey).exists(_.equals(k))).map { case ((r, _), v) => (r, v) }

  def containsColumn(columnKey: C): Boolean = columns.exists(_.equals(columnKey))

  def columnMap(): Map[C, Map[R, V]] = m.groupBy { case ((_, c), _) => c }.map { case (c, subMap) => (c, subMap.map { case ((r, _), v) => (r, v) }) }

  def columnKeySet(): Set[C] = columns.keySet

  def size(): Int = m.size

  def isEmpty: Boolean = m.isEmpty

}

object Table {

  case class Cell[R, C, V](rowKey: R, columnKey: C, value: V)

  def empty[R, C, V] = new Table[R, C, V](Map.empty, Map.empty, Map.empty)

  def apply[R, C, V](m: Map[(R, C), V]): Table[R, C, V] = {
    val rows: Map[R, List[(R, C)]] = m.keys.groupBy { case (r, c) => r }.map { case (r, keys) => r -> keys.toList }
    val columns: Map[C, List[(R, C)]] = m.keys.groupBy { case (r, c) => c }.map { case (c, keys) => c -> keys.toList }
    new Table[R, C, V](m, rows, columns)
  }

}
包utils.collections
导入utils.collections.Table.Cell
类表[R,C,V](val m:Map[(R,C),V),val行:Map[R,List[(R,C)],val列:Map[C,List[(R,C)]){
def containsValue(值:V):布尔值=m.values.exists(u.equals(值))
def values():List[V]=m.values.toList
def get(rowKey:R,columnKey:C):选项[V]=m.get(rowKey,columnKey)
def应用(行键:R,列键:C):V=m.apply((行键,列键))
def cellSet():Set[Cell[R,C,V]=m.map{case((R,C,V)=>Cell(R,C,V)}.toSet
def contains(rowKey:R,columnKey:C):Boolean=m.contains((rowKey,columnKey))
def put(行键:R,列键:C,值:V):表[R,C,V]={
val键:(R,C)=(行键,列键)
新桌子(
m=m+((键,值)),
rows=rows+((rowKey,key::rows.getOrElse(rowKey,List.empty)),
columns=columns+((columnKey,key::columns.getOrElse(columnKey,List.empty)))
)
}
def putAll(表:表[;列+((列键,键WithColumn.diff(列表键)))
大小写=>列-列键
}
新桌子(
m=m-键,
行=更新行,
columns=更新的columns
)
}
def row(rowKey:R):Map[C,V]=m.filterKeys(k=>rows.get(rowKey).存在(u.equals(k)).Map{case(u,C,V)=>(C,V)}
def containsRow(rowKey:R):布尔值=行。存在(u.equals(rowKey))
def rowMap():Map[R,Map[C,V]]=m.groupBy{case((R,u),)=>R}.Map{case(R,subMap)=>(R,subMap.Map{case((R,C,V)=>(C,V)}
def rowKeySet():设置[R]=rows.keySet
def column(columnKey:C):Map[R,V]=m.filterKeys(k=>columns.get(columnKey).存在(u.equals(k)).Map{case((R,V)=>(R,V)}
def containsColumn(columnKey:C):布尔值=columns.exists(u.equals(columnKey))
def columnMap():Map[C,Map[R,V]]=m.groupBy{case(((u,C),_)=>C}.Map{case(C,subMap)=>(C,subMap.Map{case((R,u),V)=>(R,V)}
def columnKeySet():设置[C]=columns.keySet
def size():Int=m.size
def isEmpty:Boolean=m.isEmpty
}
对象表{
案例类单元格[R,C,V](行键:R,列键:C,值:V)
def empty[R,C,V]=新表[R,C,V](Map.empty,Map.empty,Map.empty)
def应用[R,C,V](m:Map[(R,C,V]):表[R,C,V]={
val行:Map[R,List[(R,C)]]=m.keys.groupBy{case(R,C)=>R}.Map{case(R,keys)=>R->keys.toList}
val列:Map[C,List[(R,C)]]=m.keys.groupBy{case(R,C)=>C}.Map{case(C,keys)=>C->keys.toList}
新表[R,C,V](m,行,列)
}
}

我想你可以用
Map[(R,C),V]
代替
Table
Map[T,Int]
代替
Multiset
。我看不出我能做
Map[T,Int]。添加(“mykey”)
然后
Map[T,Int]。大小(“mykey”)
它将返回我为
add
添加的
T
类型的代码样本太大,无法评论。作为答案添加。请注意,如果要计算集合中的元素,不需要在scala中使用
Multiset
,您可以像这样使用
groupBy
val counts=elements.groupBy(identity).map{case(k,v)=>k->v.size}和defaultvalue 0
。如果我们想要并发,那么就映射到
def setAdd(e:T,i:Int=1)={val cnt=m.getOrElse(e,0)+i
如果我们想要并发,我们将添加并发性…这不是意味着我们正在重新实现guava ConcurrentMultiset吗?@Jas:在不同的线程中共享可变集合-我不认为这是scala方式。@Jas:注意这个实现是不可变的。您如何查询映射[(R,C),V]对于与给定的R(或C)相对应的所有映射?我的意思是,不过滤整个映射…您好。请不要将代码作为答案转储,请解释您的思路,以便用户能够理解发生了什么。干杯!这是将
map[(R,C),V]
作为委托集合来实现guava表接口。