1
1
package org .threeten .bp .zone
2
2
3
3
import java .util
4
- import java .util .{Collection => JCollection , Map => JMap , Set => JSet }
4
+ import java .util .{Collection => JCollection , Map => JMap , SortedMap => JSortedMap , Set => JSet }
5
5
import java .util .AbstractMap
6
6
import java .util .AbstractMap .SimpleEntry
7
7
import java .util .Comparator
8
8
9
9
import scala .reflect .ClassTag
10
10
import scala .collection .JavaConverters ._
11
+ import scala .collection .immutable
11
12
12
13
// TreeMap is not available in Scala.js however it is needed for Time Zone support
13
- // This is a simple implementation of NavigableMap
14
- private [zone] class ZoneMap [K : ClassTag , V ](implicit ordering : Ordering [K ]) extends AbstractMap [K , V ] with java.util.NavigableMap [K , V ] {
15
- // Use an immutable TreeMap and replace it completely on updates
16
- private var map = scala.collection.immutable.TreeMap [K , V ]()
17
-
18
- override def descendingMap () = ???
14
+ // This is a simple implementation of NavigableMap, performance is likely terrible
15
+ private [bp] class ZoneMap [K : ClassTag , V ] private [bp] (var map : immutable.TreeMap [K , V ])(implicit ordering : Ordering [K ]) extends AbstractMap [K , V ] with java.util.NavigableMap [K , V ] {
16
+ def this ()(implicit ordering : Ordering [K ]) =
17
+ this (immutable.TreeMap [K , V ]())
18
+
19
+ override def descendingMap (): java.util.NavigableMap [K , V ] = {
20
+ val ord = ordering.reverse
21
+ new ZoneMap [K , V ](map)
22
+ }
19
23
20
24
override def firstEntry (): java.util.Map .Entry [K , V ] = {
21
25
val fk = firstKey()
22
- map.get(fk).map(new SimpleEntry (firstKey() , _)).getOrElse(null .asInstanceOf [java.util.Map .Entry [K , V ]])
26
+ map.get(fk).map(new SimpleEntry (fk , _)).getOrElse(null .asInstanceOf [java.util.Map .Entry [K , V ]])
23
27
}
24
28
25
- override def navigableKeySet () = ???
29
+ override def higherEntry (key : K ): java.util.Map .Entry [K , V ] = {
30
+ val k = map.filterKeys(x => ordering.compare(x, key) > 0 )
31
+ if (k.isEmpty) null .asInstanceOf [java.util.Map .Entry [K , V ]] else new SimpleEntry (k.head._1, k.head._2)
32
+ }
26
33
27
- override def subMap (fromKey : K , fromInclusive : Boolean , toKey : K , toInclusive : Boolean ) = ???
34
+ override def ceilingEntry (key : K ): java.util.Map .Entry [K , V ] = {
35
+ val k = map.filterKeys(x => ordering.compare(x, key) >= 0 )
36
+ if (k.isEmpty) null .asInstanceOf [java.util.Map .Entry [K , V ]] else new SimpleEntry (k.head._1, k.head._2)
37
+ }
28
38
29
- override def subMap (fromKey : K , toKey : K ) = ???
39
+ override def pollFirstEntry (): java.util.Map .Entry [K , V ] = {
40
+ val fk = firstKey()
41
+ val entry = map.get(fk).map(new SimpleEntry (fk, _)).getOrElse(null .asInstanceOf [java.util.Map .Entry [K , V ]])
42
+ map -= fk
43
+ entry
44
+ }
30
45
31
- override def headMap (toKey : K , inclusive : Boolean ) = ???
46
+ override def floorEntry (key : K ): java.util.Map .Entry [K , V ] = {
47
+ val k = map.filterKeys(x => ordering.compare(x, key) <= 0 )
48
+ if (k.isEmpty) null .asInstanceOf [java.util.Map .Entry [K , V ]] else new SimpleEntry (k.last._1, k.last._2)
49
+ }
32
50
33
- override def headMap (toKey : K ) = ???
51
+ override def lowerEntry (key : K ): java.util.Map .Entry [K , V ] = {
52
+ val k = map.filterKeys(x => ordering.compare(x, key) < 0 )
53
+ if (k.isEmpty) null .asInstanceOf [java.util.Map .Entry [K , V ]] else new SimpleEntry (k.last._1, k.last._2)
54
+ }
34
55
35
- override def ceilingKey (key : K ) = ???
56
+ override def pollLastEntry (): java.util.Map .Entry [K , V ] = {
57
+ val lk = lastKey()
58
+ val entry = map.get(lk).map(new SimpleEntry (lk, _)).getOrElse(null .asInstanceOf [java.util.Map .Entry [K , V ]])
59
+ map -= lk
60
+ entry
61
+ }
36
62
37
- override def higherEntry (key : K ) = ???
63
+ override def lastEntry (): java.util.Map .Entry [K , V ] = {
64
+ val lk = lastKey()
65
+ map.get(lk).map(new SimpleEntry (lk, _)).getOrElse(null .asInstanceOf [java.util.Map .Entry [K , V ]])
66
+ }
38
67
39
- override def ceilingEntry (key : K ) = ???
68
+ // Will not be implemented. It needs NavigableSet
69
+ override def navigableKeySet () = ???
40
70
41
- override def pollFirstEntry () = ???
71
+ override def subMap (fromKey : K , fromInclusive : Boolean , toKey : K , toInclusive : Boolean ) = {
72
+ val hk = if (toInclusive) map.filterKeys(x => ordering.compare(x, toKey) <= 0 ) else
73
+ map.filterKeys(x => ordering.compare(x, toKey) < 0 )
74
+ val fk = if (fromInclusive) map.filterKeys(x => ordering.compare(x, fromKey) >= 0 ) else
75
+ map.filterKeys(x => ordering.compare(x, fromKey) > 0 )
76
+ val intersect = hk.keySet.intersect(fk.keySet).map(k => k -> hk.get(k).getOrElse(fk(k))).toMap
77
+ new ZoneMap (immutable.TreeMap (intersect.toSeq: _* ))
78
+ }
42
79
43
- override def floorKey ( key : K ) = ???
80
+ override def subMap ( fromKey : K , toKey : K ) = subMap(fromKey, true , toKey, false )
44
81
45
- override def floorEntry (key : K ) = ???
82
+ override def headMap (toKey : K , inclusive : Boolean ): java.util.NavigableMap [K , V ] = {
83
+ val k = if (inclusive) map.filterKeys(x => ordering.compare(x, toKey) <= 0 ) else
84
+ map.filterKeys(x => ordering.compare(x, toKey) < 0 )
85
+ if (k.isEmpty) new ZoneMap (immutable.TreeMap ()) else new ZoneMap (immutable.TreeMap (k.toSeq: _* ))
86
+ }
46
87
47
- override def lowerEntry ( key : K ) = ???
88
+ override def headMap ( toKey : K ): JSortedMap [ K , V ] = headMap(toKey, false )
48
89
49
- override def pollLastEntry () = ???
90
+ override def ceilingKey (key : K ): K = {
91
+ val k = map.filterKeys(x => ordering.compare(x, key) >= 0 )
92
+ if (k.isEmpty) null .asInstanceOf [K ] else k.head._1
93
+ }
50
94
51
- override def descendingKeySet () = ???
95
+ override def floorKey (key : K ): K = {
96
+ val k = map.filterKeys(x => ordering.compare(x, key) <= 0 )
97
+ if (k.isEmpty) null .asInstanceOf [K ] else k.last._1
98
+ }
52
99
53
- override def lastEntry (): java.util.Map .Entry [K , V ] = {
54
- val fk = firstKey()
55
- map.get(fk).map(new SimpleEntry (lastKey(), _)).getOrElse(null .asInstanceOf [java.util.Map .Entry [K , V ]])
56
- }
100
+ // Will not be implemented. It needs NavigableSet
101
+ override def descendingKeySet () = ???
57
102
58
- override def tailMap (fromKey : K , inclusive : Boolean ) = ???
103
+ override def tailMap (fromKey : K , inclusive : Boolean ): java.util.NavigableMap [K , V ]= {
104
+ val k = if (inclusive) map.filterKeys(x => ordering.compare(x, fromKey) >= 0 ) else
105
+ map.filterKeys(x => ordering.compare(x, fromKey) > 0 )
106
+ if (k.isEmpty) new ZoneMap (immutable.TreeMap ()) else new ZoneMap (immutable.TreeMap (k.toSeq: _* ))
107
+ }
59
108
60
- override def tailMap (fromKey : K ) = ???
109
+ override def tailMap (fromKey : K ): JSortedMap [ K , V ] = tailMap(fromKey, true )
61
110
62
- override def lowerKey (key : K ) = ???
111
+ override def lowerKey (key : K ): K = {
112
+ val k = map.filterKeys(x => ordering.compare(x, key) < 0 )
113
+ if (k.isEmpty) null .asInstanceOf [K ] else k.last._1
114
+ }
63
115
64
- override def higherKey (key : K ) = ???
116
+ override def higherKey (key : K ) = {
117
+ val k = map.filterKeys(x => ordering.compare(x, key) > 0 )
118
+ if (k.isEmpty) null .asInstanceOf [K ] else k.head._1
119
+ }
65
120
66
121
override def firstKey (): K = map.firstKey
67
122
@@ -72,16 +127,22 @@ private[zone] class ZoneMap[K: ClassTag, V](implicit ordering: Ordering[K]) exte
72
127
override def values (): JCollection [V ] = map.values.asJavaCollection
73
128
74
129
override def put (key : K , value : V ): V = {
75
- map = map + ((key, value))
76
- value
130
+ val prev : Option [V ] = map.get(key)
131
+ map += ((key, value))
132
+ prev.getOrElse(null .asInstanceOf [V ])
77
133
}
78
134
79
135
override def clear (): Unit =
80
- map = scala.collection. immutable.TreeMap [ K , V ] ()
136
+ map = immutable.TreeMap ()
81
137
82
138
override def entrySet (): JSet [JMap .Entry [K , V ]] = {
83
139
map.map {
84
140
case (k, v) => new SimpleEntry [K , V ](k, v): JMap .Entry [K , V ]
85
141
}.toSet.asJava
86
142
}
87
143
}
144
+
145
+ object ZoneMap {
146
+
147
+ def apply [K : ClassTag , V ](map : immutable.TreeMap [K , V ])(implicit ordering : Ordering [K ]): java.util.NavigableMap [K , V ] = new ZoneMap [K , V ](map)
148
+ }
0 commit comments