You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Moritz Petersen <mo...@mac.com> on 2002/10/12 22:51:41 UTC

[PATCH] [collections] new: MapUtils#asMap(Object[]) and MapUtils#toMapEntry(Object)

Index: MapUtils.java
===================================================================
RCS file:  
/home/cvspublic/jakarta-commons/collections/src/java/org/apache/ 
commons/collections/MapUtils.java,v
retrieving revision 1.12
diff -u -r1.12 MapUtils.java
--- MapUtils.java	19 Aug 2002 21:56:18 -0000	1.12
+++ MapUtils.java	12 Oct 2002 20:46:26 -0000
@@ -1166,4 +1166,74 @@
      public static SortedMap lazySortedMap(SortedMap map, Factory  
factory) {
          return new LazySortedMap(map, factory);
      }
+
+
+    /**
+     * Converts the given array into a {@link Map}. Each element of  
the array
+     * must be either a {@link Map.Entry} or an Array, containing at  
least two
+     * elements, where the first element is used as key and the second  
as
+     * value. This method can be used to initialize:
+     *
+     * <pre>
+     * // Create a Map mapping colors.
+     * Map colorMap = MapUtils.asMap(new String[][] {{
+     *     {"RED", "#FF0000"},
+     *     {"GREEN", "#00FF00"},
+     *     {"BLUE", "#0000FF"}});
+     * </pre>
+     *
+     * @param array an array whose elements are either a {@link  
Map.Entry} or
+     * an Array, containing at least two elements.
+     * @throws ArrayIndexOutOfBoundsException if one elment of this  
Array is
+     * itself an Array containing less then two elements.
+     * @throws IllegalArgumentException if the array contains elements  
other
+     * than {@link Map.Entry} and an Array.
+     * @throws NullPointerException if the array contains  
<code>null</code>
+     * elements.
+     * @return a Map that was created from the array.
+     * @see #toMapEntry(Object)
+     */
+    public static Map asMap(Object[] array) {
+        Map map = new HashMap(array.length);
+        for (int i = 0; i < array.length; i++) {
+            Map.Entry entry = toMapEntry(array[i]);
+            map.put(entry.getKey(), entry.getValue());
+        }
+        return map;
+    }
+
+
+    /**
+     * Wraps the {@link Map.Entry} interface around the given object.  
This
+     * method will fail, if the object is neither instance of {@link
+     * Map.Entry} nor an Array (of at least <code>length >= 2</code>).  
If the
+     * object is an Array, then the first element will be used as
+     * key and the second will be used as value.
+     * <p>
+     * <b>Caution:</b> if the Array contains less then two elements, an
+     * {@link ArrayIndexOutOfBoundsException} will not be thrown  
before the
+     * {@link Map.Entry}'s {@link Map.Entry#getKey()} or {@link
+     * Map.Entry#getValue()} methods are used.
+     *
+     * @param object will be used as the core of the {@link  
Map.Entry}. Must
+     * be either an instance of {@link Map.Entry} or an Array of at  
least
+     * <code>length >= 2</code>).
+     * @return the object itself, if it is an instance of {@link  
Map.Entry} or
+     * a new instance of {@link Map.Entry}, if the object is an Array.
+     * @throws IllegalArgumentException if the object is neither  
instance of
+     * {@link Map.Entry} nor an Array.
+     * @throws NullPointerException if the object is <code>null</code>.
+     */
+    public static Map.Entry toMapEntry(Object object) {
+        if (object instanceof Map.Entry) {
+            return (Map.Entry) object;
+        } else if (object.getClass().isArray()) {
+            Object[] array = (Object[]) object;
+            return new DefaultMapEntry(array[0], array[1]);
+        } else {
+            throw new IllegalArgumentException(object
+                    + " is neither of type Map.Entry nor an Array.");
+        }
+    }
+
  }


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] [collections] new: MapUtils#asMap(Object[]) and MapUtils#toMapEntry(Object)

Posted by Moritz Petersen <mo...@mac.com>.
>> To summarize the pros and cons:
>>
>> asMap                | toMap
>> -------------------------------------------
>> creates a new        | creates a new
>> instance             | instance of a
>>                       | wrapper class
>> -------------------------------------------
>> populates the new    | accesses the backing
>> instance in the      | array only on demand
>> moment it is created |
>> -------------------------------------------
>>
>> If I am not wrong, the advantage of the to... methods is, that the
>> wrapper class is backed up by the array, and will access its elements
>> only on demand.(?)
>
> Part of the confusion is that you've swapped the names around. The 
> method
> you've coded should be called toMap, not asMap.
>
> The terms have meanings as follows:
> 'to' - convert an object from one type to another leaving the original
> unaffected
> 'as' - provide a view of an object as another type, changes to the 
> original
> are thus seen through the view
>
> The asMap method will require a new inner class within MapUtils. Its
> operation is similar to Collections.asList from the JDK.

OK, I'll take a look...

>
>> Another word about the toMapEntry() method. Maybe it should be renamed
>> to asMapEntry(). The reason why it is called toMapEntry() is, that I 
>> in
>> fact created a wrapper class, that implemented the Map.Entry 
>> interface.
>> But then I realized, that there is already a DefaultMapEntry class,
>> which I could use. So I exchanged my anonymous inner class with the
>> DefaultMapEntry.
>
> I think that DefaultMapEntry is a JDK1.4 class. Also, I wouldn't 
> support
> adding toMapEntry as a public method. My suggestion would be to merge
> toMapEntry into toMap, thus removing the need to reference 
> DefaultMapEntry,
> and removing a temporary object creation.

No. DefaultMapEntry is part of org.apache.commons.collections.

> PS. I am trying to organise a release at present, so the patch probably
> won't get committed until that is done.

No problem. I'm gonna refine the code and complete it.

BTW, I also didn't like the idea of toMapEntry being a public method. 
It is quite easy to code it inside of toMap().

So, if you don't mind, I rename asMap() to toMap(), remove toMapEntry() 
and that's it for the moment. The next patches will be delivered as 
text file.

Regards,

Moritz.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] [collections] new: MapUtils#asMap(Object[]) and MapUtils#toMapEntry(Object)

Posted by Stephen Colebourne <sc...@btopenworld.com>.
From: "Moritz Petersen" <mo...@mac.com>
> Sorry, that I forgot to send the test case together with the first
> mail. A typical newbie mistake, I guess.

Thats OK, but we would definitely prefer them as attachments as the mail
system messes up the lines otherwise ;-)
> To summarize the pros and cons:
>
> asMap                | toMap
> -------------------------------------------
> creates a new        | creates a new
> instance             | instance of a
>                       | wrapper class
> -------------------------------------------
> populates the new    | accesses the backing
> instance in the      | array only on demand
> moment it is created |
> -------------------------------------------
>
> If I am not wrong, the advantage of the to... methods is, that the
> wrapper class is backed up by the array, and will access its elements
> only on demand.(?)

Part of the confusion is that you've swapped the names around. The method
you've coded should be called toMap, not asMap.

The terms have meanings as follows:
'to' - convert an object from one type to another leaving the original
unaffected
'as' - provide a view of an object as another type, changes to the original
are thus seen through the view

The asMap method will require a new inner class within MapUtils. Its
operation is similar to Collections.asList from the JDK.

> Another word about the toMapEntry() method. Maybe it should be renamed
> to asMapEntry(). The reason why it is called toMapEntry() is, that I in
> fact created a wrapper class, that implemented the Map.Entry interface.
> But then I realized, that there is already a DefaultMapEntry class,
> which I could use. So I exchanged my anonymous inner class with the
> DefaultMapEntry.

I think that DefaultMapEntry is a JDK1.4 class. Also, I wouldn't support
adding toMapEntry as a public method. My suggestion would be to merge
toMapEntry into toMap, thus removing the need to reference DefaultMapEntry,
and removing a temporary object creation.

Stephen

PS. I am trying to organise a release at present, so the patch probably
won't get committed until that is done.



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] [collections] new: MapUtils#asMap(Object[]) and MapUtils#toMapEntry(Object)

Posted by Moritz Petersen <mo...@mac.com>.
Sorry, that I forgot to send the test case together with the first 
mail. A typical newbie mistake, I guess.

Ok, some explanations to the patch:

I first realized the most simple method of all: asMap(Object[]). This 
method just creates a new Map and returns it. By using the 
toMapEntry(Object) method, it is possible to do it with almost no 
effort.
Now my ignorance takes control, because I still don't understand the 
difference in semantics between to... and as...

to... wraps and as... initializes a new object. Good.

But what is the _use_ of to...? (There will some useful pages in the 
web, explaining this topic, I guess. Links are appreciated.).

If I implement the toMap(Object[]) method, I need a wrapper class that 
implements the Map interface and is backed up by the given Object[] 
array. The problem for me is, that the use of it will be very 
expensive. So, why not just create a new object using asMap()?

To summarize the pros and cons:

asMap                | toMap
-------------------------------------------
creates a new        | creates a new
instance             | instance of a
                      | wrapper class
-------------------------------------------
populates the new    | accesses the backing
instance in the      | array only on demand
moment it is created |
-------------------------------------------


If I am not wrong, the advantage of the to... methods is, that the 
wrapper class is backed up by the array, and will access its elements 
only on demand.(?)


Another word about the toMapEntry() method. Maybe it should be renamed 
to asMapEntry(). The reason why it is called toMapEntry() is, that I in 
fact created a wrapper class, that implemented the Map.Entry interface. 
But then I realized, that there is already a DefaultMapEntry class, 
which I could use. So I exchanged my anonymous inner class with the 
DefaultMapEntry.


-Moritz.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>