19
Set<String> keys = mappings.keySet();
String[] keyArray = (String[]) keys.toArray();

String hashmapDetails = "";
for(int p=0; p < keyArray.length; p++){
    String[] details = keyArray[p].split("/");
    hashmapDetails += details[1];
    hashmapDetails += mappings.get(keyArray[p]);
    if (p != keyArray.length -1){
        hashmapDetails += ";";
    }
}

Pardon my lack of understanding but I'm trying to explore the usage of hashmaps. I understand that the toArray() returns an Object[]. However, is it not possible to type cast it to a String[]? As you can see in the codes, later, I need to go through an array and do some splitting and other String manipulation.

By doing this I got an error:

java.lang.ClassCastException: java.lang.Object[] cannot be cast to java.lang.String[]

Any guidance on how I should tackle this is greatly appreciated. Thanks!

lyk
  • 1,578
  • 5
  • 25
  • 49

3 Answers3

27

You can't simply cast an Object[] array to a String[] array. You should instead use the generic version of toArray, which should work better:

String[] keyArray = keys.toArray(new String[keys.size()]);

Also note that you could simply iterate over the entrySet (that will save all the get calls) and use a StringBuilder for better string concatenation efficiency:

StringBuilder hashmapDetails = new StringBuilder();
for(Map.Entry<String, String> e : mappings.entrySet()) {
    String[] details = e.getKey().split("/");
    hashmapDetails += details[1];
    hashmapDetails += e.getValue();
    hashmapDetails += ";";
}

String result = hashmapDetails.substring(0, hashmapDetails.length() - 1);
assylias
  • 321,522
  • 82
  • 660
  • 783
  • Thanks for your help! The first solution with the generic version of toArray was good enough for me, thank you! =) – lyk Apr 18 '13 at 08:26
  • 1
    The `toArray(new String[0])` version is definitely the way to go. It's concise and expresses exactly what you're doing. – NRitH Sep 19 '13 at 21:34
  • @NRitH possibly but it creates an unnecessary object so I prefer the "sized" version. – assylias Sep 20 '13 at 00:55
  • @assylias IIRC, the version of toArray() that takes an array argument just uses the argument to determine the returned class type, so the size of the array you pass in is immaterial. – NRitH Sep 20 '13 at 01:50
  • 2
    @NRitH that is not the case. If the array is big enough, it is used, otherwise a new array is created. It is explained in the javadoc: http://docs.oracle.com/javase/7/docs/api/java/util/List.html#toArray(T[]) - see also: http://stackoverflow.com/questions/174093/toarraynew-myclass0-or-toarraynew-myclassmylist-size – assylias Sep 20 '13 at 05:59
  • @assylias Interesting. I wonder whether that's new, because I don't remember the Javadoc saying that previously. – NRitH Sep 20 '13 at 11:40
  • @NRitH it has been the case since at least Java 4, documented in the parameters section: http://docs.oracle.com/javase/1.4.2/docs/api/java/util/List.html#toArray(java.lang.Object[]) – assylias Sep 20 '13 at 11:45
7

It is possible to cast keyset to String[]. Try this:

String[] keys = map.keySet().toArray(new String[0]);
Adnan
  • 5,025
  • 5
  • 25
  • 44
2

You could just iterate through the Set, I don't think the toArray step is necessary. Something like this:

Set<String> keys = mappings.keySet();

String hashmapDetails = "";
for(String key : keys){
    String[] details = key.split("/");
    hashmapDetails += details[1];
    hashmapDetails += mappings.get(key);
    if (p != keys.size() -1){
        hashmapDetails += ";";
    }
}
Rodrigo Sasaki
  • 7,048
  • 4
  • 34
  • 49