要在scala中使用番石榴Table
和Multiset
?在scala中是否有不同的concenpts,而不是爲了這個用途而導入guava庫?有番石榴MultiSet和表概念的Scala替代品嗎?
3
A
回答
5
您可以使用Map[(R, C), V]
而不是Table<R, C, V>
和Map[T, Int]
而不是Multiset<T>
。你也可以添加輔助方法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
1
這是使用Map[(R, C), V]
作爲委託收集第一天真的實現。 rows
和columns
被用作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)
}
}
+0
你好。請不要將代碼轉儲爲答案,請解釋您的思路,以便用戶瞭解正在發生的事情。乾杯! – Cthulhu
+0
這是使用'Map [(R,C),V]'作爲委託集合的番石榴Table接口的實現。 –
相關問題
- 1. 番石榴表替代
- 2. 番石榴的原始替代表
- 3. 在番石榴的RangeSet /範圍沒有「大小」的概念?
- 4. 有沒有番石榴的概述?
- 5. 番石榴表ConcurrentModificationException
- 6. 番石榴和javafx
- 7. 番石榴和Weblogic:ClassNotFoundException
- 8. Floats.tryParse()番石榴
- 9. 番石榴:Throwables.propagate和InterruptedException的
- 10. 番石榴有雙向功能嗎?
- 11. ClassNotFoundException的番石榴
- 12. 使用番石榴表
- 13. 遍歷表番石榴
- 14. 番石榴Multimap列表
- 15. 番石榴多集和Multipmap
- 16. 番石榴,Files.readLines()和空白
- 17. 番石榴是否有空?
- 18. 加法表番石榴和arraylist
- 19. 番石榴映射
- 20. 番石榴資源
- 21. 番石榴入門
- 22. Java番石榴CartesianProduct
- 23. 番石榴功能
- 24. 番石榴 - 地圖支持番石榴功能
- 25. 番石榴迭代器嵌套的foreach
- 26. 番石榴的HashBaseTable cellSet()
- 27. 子類番石榴的ImmutableSet
- 28. 番石榴LoadingCache:內的CacheLoader
- 29. C#.Net中LoadingCache(番石榴)的替代方案4
- 30. 番石榴/測試迭代器實現
我想你可以使用'地圖,而不是'表'和''代替多重集''地圖[T,INT] [(R,C),V]'。 –
senia
我看不到我可以做Map [T,Int] .add(「mykey」),然後是Map [T,Int] .size(「mykey」),它會返回我添加的項目數類型'T' – Jas
'add'的代碼示例太大而無法評論。作爲回答添加。 – senia