lib/collection: better doc for Iterator
[nit.git] / lib / standard / collection / abstract_collection.nit
index bb17064..2f7e454 100644 (file)
@@ -66,6 +66,14 @@ interface Collection[E]
        #     assert [1..1[.is_empty   == true
        fun is_empty: Bool do return length == 0
 
+       # Alias for `not is_empty`.
+       #
+       # Some people prefer to have conditions grammatically easier to read.
+       #
+       #     assert [1,2,3].not_empty  == true
+       #     assert [1..1[.not_empty   == false
+       fun not_empty: Bool do return not self.is_empty
+
        # Number of items in the collection.
        #
        #     assert [10,20,30].length == 3
@@ -171,8 +179,9 @@ interface Collection[E]
        end
 end
 
-# Instances of the Iterator class generates a series of elements, one at a time.
-# They are mainly used with collections.
+# Iterators generate a series of elements, one at a time.
+#
+# They are mainly used with collections and obtained from `Collection::iterator`.
 interface Iterator[E]
        # The current item.
        # Require `is_ok`.
@@ -203,7 +212,7 @@ end
 #
 # Used to pass arguments by reference.
 #
-# Also used when one want to give asingle element when a full
+# Also used when one want to give a single element when a full
 # collection is expected
 class Container[E]
        super Collection[E]
@@ -305,7 +314,7 @@ end
 #      # ...
 #      s.add(a)
 #      assert s.has(b)      ==  true
-interface Set[E: Object]
+interface Set[E]
        super SimpleCollection[E]
 
        redef fun has_only(item)
@@ -416,7 +425,14 @@ interface MapRead[K, V]
                return default
        end
 
-       # Alias for `keys.has`
+       # Is there an item associated with `key`?
+       #
+       #     var x = new HashMap[String, Int]
+       #     x["four"] = 4
+       #     assert x.has_key("four") == true
+       #     assert x.has_key("five") == false
+       #
+       # By default it is a synonymous to `keys.has` but could be redefined with a direct implementation.
        fun has_key(key: K): Bool do return self.keys.has(key)
 
        # Get a new iterator on the map.
@@ -466,6 +482,49 @@ interface MapRead[K, V]
        # Note: the value is returned *as is*, implementations may want to store the value in the map before returning it
        # @toimplement
        protected fun provide_default_value(key: K): V do abort
+
+       # Does `self` and `other` have the same keys associated with the same values?
+       #
+       # ~~~
+       # var a = new HashMap[String, Int]
+       # var b = new ArrayMap[Object, Numeric]
+       # assert a == b
+       # a["one"] = 1
+       # assert a != b
+       # b["one"] = 1
+       # assert a == b
+       # b["one"] = 2
+       # assert a != b
+       # ~~~
+       redef fun ==(other)
+       do
+               if not other isa MapRead[nullable Object, nullable Object] then return false
+               if other.length != self.length then return false
+               for k, v in self do
+                       if not other.has_key(k) then return false
+                       if other[k] != v then return false
+               end
+               return true
+       end
+
+       # A hashcode based on the hashcode of the keys and the values.
+       #
+       # ~~~
+       # var a = new HashMap[String, Int]
+       # var b = new ArrayMap[Object, Numeric]
+       # a["one"] = 1
+       # b["one"] = 1
+       # assert a.hash == b.hash
+       # ~~~
+       redef fun hash
+       do
+               var res = length
+               for k, v in self do
+                       if k != null then res += k.hash * 7
+                       if v != null then res += v.hash * 11
+               end
+               return res
+       end
 end
 
 # Maps are associative collections: `key` -> `item`.
@@ -963,6 +1022,8 @@ interface CoupleMap[K, V]
                        return c.second
                end
        end
+
+       redef fun has_key(key) do return couple_at(key) != null
 end
 
 # Iterator on CoupleMap