In java, how can I work with objects that can be either String or List <String>?

Possible duplicate:
Maps with multiple types of values ​​in java

I have a strange question. Maybe I'm going to do it wrong, but let's see where this question is :)

I need a map container containing strings or lists of strings. I want to apply this rule during the construction of this object so that you cannot create a map with values ​​that are neither one nor the other.

eg.

class Record { public Record(String key, Map<String,Object> attrs) { // check that attrs only contains Objects which are Strings or List<Strings> } } 

Other ways that I decided to solve may be ...

one)

 class Record { public Record(String key, Map<String,String> attrs, Map<String,List<String>> multiAttrs) { // ... } } 

2)

 class Record { public Record(String key, Map<String,Value> attrs) { // ... } } class Value { // Create some funky class that encapsulates lists. // Perhaps returning the only element in the list if the size is 1, // but returning the list otherwise } 

I am not interested in alternatives, but I just put it there, as I already saw. In fact, I want the difference between the lines and the list to be transparent to the class user.

0
java
source share
4 answers

Check out ArrayListMultimap from Google to help with this need

You can continue calling put on this card, if you need to get a card in a simplified form, you can use this method or change it :)

 public static Map<Field, String> toSingularMap(ArrayListMultimap<Field, String> map) { Map<Field, String> singular_map = new HashMap<Field, String>(); if (map != null && !map.isEmpty()) { Map<Field, Collection<String>> real_map = map.asMap(); for (Iterator<Entry<Field, Collection<String>>> it = real_map .entrySet().iterator(); it.hasNext();) { Entry<Field, Collection<String>> entry = it.next(); Field field = entry.getKey(); Collection<String> values = entry.getValue(); String value = null; if (values != null && !values.isEmpty()) { ArrayList<String> list = new ArrayList<String>(values); value = list.get(0); } singular_map.put(field, value); } } return singular_map; } 

Or, if you do not want to use an additional library, you can create a simple Wrapper class

 class Wrap { String value; String[] values } 

and use your map Map<String, Wrap> map , when looping, you can define either using your class methods or just testing, which is filled with one of the Wrapper variables

+2
source share

Have you considered ListMultimap ? For the case with one value, there will be only one element in the list. Multimap allows Multimap to display multiple elements (values) for each key. So your method will be:

 public Record(String key, ListMultimap<String, String> attrs)... 

Also, since your Record seems to be a different display, consider using Table , which allows you to display two keys.

+2
source share

Why not create a class

 class MyFunkyValue{ private String onlyOneString; private List<String> stringValues; public MyFunkyValue(String s){ ... } public MyFunkyValue(List<String>ls){ ... } } 

and use it as follows:

 Map<KeyClass,MyFunkyValue> m; 
+1
source share

I would use only List<String> . Perhaps you can add several methods to add a single line and wrap the passed argument using Arrays.asList(...) . Using only one type of object will reduce the amount of code to write and avoid many if/else .

+1
source share

All Articles