1

I have a class with a HashMap<k,v>. The type of the values of this HashMap is a static class which has two different objects as attributes. i.e.,

   public class Example {
      private HashMap<String, StaticClassExample> map;
      private static class StaticClassExample {
           private Object1 o1;
           private Object2 o2;
           //...   
      }
      //...
   }

And my question is how can I do this operation efficiently:

   public List<Object1> getAllObject1() {}

I know that I can do: map.values() and then iterate the values collection and get Object1 from each StaticClassExample, but this wouldn't be efficient. It's possible what I ask or I must create another hashmap for my purpose?

Charles Sprayberry
  • 7,741
  • 3
  • 41
  • 50
LiLou1
  • 31
  • 1
  • 5
  • 3
    What does it being a static class have to do with anything? Surely the only thing that's relevant is you want a projection from the map values. Frankly it's going to be hard to make this very efficient (no iteration) without also making it pretty brittle... do you definitely need a `List` instead of just an `Iterable`? – Jon Skeet Jan 28 '12 at 09:48
  • Do you really need a `List`? Otherwise, you could make it lazy... – cha0site Jan 28 '12 at 09:51
  • 1
    Yes, I need a List with the all Object1 from the hashmap. So I guess that I would have to choice another representation... – LiLou1 Jan 28 '12 at 09:51
  • 1
    Why do you believe that building a List from map.values() is inefficient? Have you profiled your program and determined that it takes 90% of the total execution time? If you haven't, then you're wasting your time worrying about meaningless things. – kdgregory Jan 28 '12 at 13:54
  • 1
    And why do you need a List? Are you passing it to some third-party library? If not, then change your code to take a `Collection`, and pass the values() result to it. – kdgregory Jan 28 '12 at 13:56
  • I don't care about the execute time, but the efficiency must be O(1) or O(log n). – LiLou1 Jan 28 '12 at 14:56
  • Thank you all for the comments, I decided to change/complete the representation of the class. I thought there might be a method to do what I wanted, but I see that it's impossible. – LiLou1 Jan 28 '12 at 15:00

1 Answers1

0

If you don't mind some memory overhead, you could keep a separate list with the o1-values:

public class HashMapList
{
    private HashMap<String, StaticClassExample> map = new HashMap<String, HashMapList.StaticClassExample>();

    private List<Object> o1List = new LinkedList<Object>();

    public static class StaticClassExample
    {
        private Object o1;
        private Object o2;
    }

    public void addStaticClassExample(String key, StaticClassExample example)
    {
        StaticClassExample oldVal = map.put(key, example);
        if(oldVal != null)
        {
            o1List.remove(oldVal.o1);
        }
        o1List.add(example.o1);
    }

    public StaticClassExample getStaticClassExampleByKey(String key)
    {
        return map.get(key);
    }

    public void removeStaticClassExampleByKey(String key)
    {
        StaticClassExample removed = map.remove(key);
        if(removed != null)
        {
            o1List.remove(removed.o1);
        }
    }

    public List<Object> getAllObject1()
    {
        return Collections.unmodifiableList(o1List);
    }   

}

Of course, this requires you to encapsule the HashMap inside the class and never give a straight access to it, because then someone using the class could modify the HashMap directly, and the List would no longer be in sync with the Map. Note that getAllObject1 returns an unmodifiable view of the internal list, so it can't be modified from outside of the class.

esaj
  • 15,875
  • 5
  • 38
  • 52