1

I need to convert a navigable map to a 2d String array.Below given is a code from an answer to one of my previous question.

NavigableMap<Integer,String> map =
        new TreeMap<Integer, String>();

map.put(0, "Kid");
map.put(11, "Teens");
map.put(20, "Twenties");
map.put(30, "Thirties");
map.put(40, "Forties");
map.put(50, "Senior");
map.put(100, "OMG OMG OMG!");

System.out.println(map.get(map.floorKey(13)));     // Teens
System.out.println(map.get(map.floorKey(29)));     // Twenties
System.out.println(map.get(map.floorKey(30)));     // Thirties
System.out.println(map.floorEntry(42).getValue()); // Forties
System.out.println(map.get(map.floorKey(666)));    // OMG OMG OMG!

I have to convert this map to a 2d String array:

{
{"0-11","Kids"},
{"11-20","Teens"},
{"20-30","Twenties"}
...
}

Is there a fast and elegant way to do this?

Community
  • 1
  • 1
Emil
  • 13,577
  • 18
  • 69
  • 108
  • `"OMG OMG OMG!"` - LOL no wonder the snippet looks familiar... – polygenelubricants Aug 26 '10 at 11:45
  • @poly:have a better solution? – Emil Aug 26 '10 at 11:48
  • @Emil: do you have to represent the data as a `String[][]`? What about a generic `List>` instead? You can get `MappedInterval.start()` and `.end()`, and `.value()`, and you can `@Override` the `toString()` to print it like `[start-end] => value` or something like that. Basically I don't think you can come up with any much better algorithm to convert to `String[][]`, but there are much better representation than `String[][]` to begin with, and I can give the snippet to do that. – polygenelubricants Aug 26 '10 at 11:54
  • Actually I wanted to show the map in Jtable.That's why I'm converting it into a 2d array – Emil Aug 26 '10 at 11:59
  • @Emil: if you have a look at the quick tutorial http://download.oracle.com/javase/tutorial/uiswing/components/table.html#simple ; they did warn that the simple model using two dimensional arrays have disadvantages. Fortunately you can define your own custom table model that would not require you to create this array, but rather get the data directly from the `NavigableMap`. – polygenelubricants Aug 26 '10 at 12:12
  • @Emil: it will also make updating the `NavigableMap` much easier in case you want to allow editing. – polygenelubricants Aug 26 '10 at 12:18
  • I don't have much idea in swing.Thanks for the info.If possible please post a sample for representing the above code in Jtable using tablemodel. – Emil Aug 26 '10 at 12:19
  • 1
    @Poly:Thanks for your comment's.I implemented the table model by tweaking a bit of this code http://www.java2s.com/Tutorial/Java/0240__Swing/MapTableModel.htm along with Marks answer. – Emil Aug 26 '10 at 12:58

2 Answers2

2

Best bet is just to iterate through the Map and create an array for each entry, the troublesome part is generating things like "0-11" since this requires looking for the next highest key...but since the Map is sorted (because you're using a TreeMap) it's no big deal.

String[][] strArr = new String[map.size()][2];
int i = 0;
for(Entry<Integer, String> entry : map.entrySet()){
    // current key
    Integer key = entry.getKey();
    // next key, or null if there isn't one
    Integer nextKey = map.higherKey(key);

    // you might want to define some behavior for when nextKey is null

    // build the "0-11" part (column 0)
    strArr[i][0] = key + "-" + nextKey;

    // add the "Teens" part (this is just the value from the Map Entry)
    strArr[i][1] = entry.getValue();

    // increment i for the next row in strArr
    i++;
}
Mark Elliot
  • 75,278
  • 22
  • 140
  • 160
  • Thanks,it works.I gave a break when nextKey is null.I'll just wait a little while longer and see if any one else gives a better one. – Emil Aug 26 '10 at 11:06
1

you can create two Arrays, one with the keys and one with the values in an "elegant way" then you can construct an String[][] using this two arrays.

// Create an array containing the values in a map 
Integer[] arrayKeys = (Integer[])map.keySet().toArray( new Integer[map.keySet().size()]); 
// Create an array containing the values in a map 
String[] arrayValues = (String[])map.values().toArray( new String[map.values().size()]); 

String[][] stringArray = new String[arrayKeys.length][2];
for (int i=0; i < arrayValues.length; i++)
{
      stringArray[i][0] = arrayKeys[i].toString() + (i+1 < arrayValues.length ? " - " + arrayKeys[i+1] : "");
      stringArray[i][1] = arrayValues[i];
}
Torres
  • 5,330
  • 4
  • 26
  • 26