HAMID
HAMID

Reputation: 985

Populating hashmap with a loop in java

Hi i have a problem populating hashmap with a loop, i need to store objects as a value and string as a key and if another element wants to be added to hashmap it should be checked against, if the value already exist, if so it should increment the the string key by 1 for example:

("JButton", JButtonObject);

another element wants to be added if again JButton it should be

("JButton1", JButtonObject);
...
...
...

my code: Thanks guys

private void CreateInstance(java.awt.event.ActionEvent evt) {                                
    // add code here

    Object object = null;
    if (evt.getSource() == CreateInstance)
    {
        int[] selectedIx = ClassList.getSelectedIndices();
        for (int i=0; i<selectedIx.length; i++) {
                Object sel = ClassList.getModel().getElementAt(selectedIx[i]);
                try {
                      Class classDefinition = Class.forName(sel.toString());
                      object = classDefinition.newInstance();
                      //create name
                      String data = sel.toString();
                      String substring = data.substring(12);
                      //check if name is unique

                      //add to map
                      hm.put(substring, object);----- HERE IS THE PROBLEM
                      System.out.println();
                } 
                catch (InstantiationException e) {
                      System.out.println(e);
                  } 
                catch (IllegalAccessException e) {
                      System.out.println(e);
                  } 
                catch (ClassNotFoundException e) {
                      System.out.println(e);
             }
             if(object instanceof java.awt.Component){
                DesignWindow.add((java.awt.Component)object);
                DesignWindow.validate();
             }
             else{
                System.out.println("Error");
             }
        }
    }
}                        

Upvotes: 4

Views: 2939

Answers (4)

卢声远 Shengyuan Lu
卢声远 Shengyuan Lu

Reputation: 32004

Define a structure:

Map<String,LinkedHashMap<String,Object>> map=new LinkedHashMap<String,LinkedHashMap<String,Object>>();

It looks like:

"Jbutton"--->#####################
             #"Jbutton" , object0#
             #"Jbutton1", object1#
             #"Jbutton2", object2#
             #####################

"JBox"  ---->##################
             #"JBox" , object0#
             #"JBox1", object1#
             #"JBox2", object2#
             ##################

Then use it in your method 'CreateInstance':

LinkedHashMap<String,Object> selectedMap=map.get(substring);
if(selectedMap==null){//First put in this kind of element
    selectedMap=new LinkedHashMap<String,Object>();
    map.put(substring, selectedMap);
}else{
    selectedMap.put(substring+ (selectedMap.size()==0? "":selectedMap.size()), object);
}

Upvotes: 2

helios
helios

Reputation: 13841

Maybe you should use another structure as everybody says. But for doing what you want to:

String substring = data.substring(12);
//check if name is unique

// add this line
String uniqueKey = findUniqueKey(hm, substring);

//add to map with the calculated value
hm.put(uniqueKey, object);----- HERE IS THE PROBLEM

and...

private String findUniqueKey(Map<String, ?> map, String prefix)
{
   if (!map.containsKey(prefix))
      return prefix;
   int i = 1;
   while(true) { // or check i against a maximum
      String candidate = prefix + i;
      if (!map.containsKey(candidate))
         return candidate;
      i++;
   }
}

This way you separate the logic for deciding the key from the rest of the code.

Sidenote: Try to use Map references. Only use HashMap for creating the instance. So your code is not linked to a particular implementation of what you need: a Map.

Upvotes: 0

Andreas Dolk
Andreas Dolk

Reputation: 114767

I don't know your actual requirement. But maybe this alternative approach to store multiple objects for a single key works too, and if it does, it will make life much easier. I wouldn't construct different keys but use one key and a list of instances for that key:

HashMap<String, List<Object>> hm = new HashMap<String, List<Object>>();

// ...

try {
  Class classDefinition = Class.forName(sel.toString());
  object = classDefinition.newInstance();
  //create name
  String data = sel.toString();
  String substring = data.substring(12);

  // new code added here:
  List<Object> objects = hm.get(substring);
  if (obejcts == null) {
    objects = new ArrayList<Object>();
    hm.put(substring, objects);
  }
  objects.add(object);

// continue with catches 

It will be a bit different to use, but you may be able to do all you wanted to do:

if (hm.get(substring) == null) { // no object stored for key substring }
int numberOfObjects = hm.get(substring).size();
Object firstObject = hm.get(substring).get(0);  // the first object for substring
List<Object> objects = hm.get(substring);  // all objects

Upvotes: 0

Will A
Will A

Reputation: 24988

Maintain a second HashMap of 'preferred key' (e.g. "JButton") to an integer, and then use the integer to determine the next suffix for the actual key you'd then use.

Upvotes: 1

Related Questions