-1

I am familiar with static variables and singletons, but I haven't seen any information on this:

public class MyImmutableClass {

    private final String string;

    public static final MyImmutableClass getInstance(String s) {

        if( a MyImmutableClass already exists with that string as its field)
            return (that instance);
        else
            return a new instance;

    }  

    ...

}  

No duplicates of MyImmutableClass could exist. Does this make sense and if so, how would you implement this?

roundar
  • 1,593
  • 1
  • 18
  • 22
  • You have the pseudocode right there. Write the corresponding Java. – Robert Harvey Jan 04 '13 at 05:35
  • That's the question. If it makes sense to do this, How do I look at all the other instances of my class to see if their field matches this one. – roundar Jan 04 '13 at 05:37
  • You need a Dictionary to register the instances, unless there's already a way to scan the instances for a name. Alas, I don't know how that would be done in Java. In C# you would put all of the instances in a `Dictionary` and retrieve an instance from the dictionary by name. – Robert Harvey Jan 04 '13 at 05:39
  • Read a book java effective (Joshua bloch) or [http://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java][1] [1]: http://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java – zapetin52 Jan 04 '13 at 05:58
  • I've read that chapter of his book(I'm reading the book now actually), he may cover this, but I don't recall this exact scenario. Also, that link is almost completely irrelevant. – roundar Jan 04 '13 at 06:03
  • I love random down votes for no apparent reason. If it's not one of the reasons listed on the tooltip over the arrows (it can't be in this case), then at least leave your reason. – roundar Jan 06 '13 at 03:31

4 Answers4

2
public final class MyImmutableClass {
private MyImmutableClass(){}
private final String string;
private static Map<String,MyImmutableClass> map = new WeakHashMap<String,MyImmutableClass>();
public static final MyImmutableClass getInstance(String s) {

    if(map.containsKey(s))
        return (map.get(s));
    else{
        MyImmutableClass temp = new MyImmutableClass(s);
        map.put(s,temp);
        return  temp;
    }
}  

...

}  

Something like this should work for you.

Subin Sebastian
  • 10,870
  • 3
  • 37
  • 42
  • Thanks, would it be better to use a WeakHashMap? – roundar Jan 04 '13 at 05:41
  • A hashtable-based Map implementation with weak keys. An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. More precisely, the presence of a mapping for a given key will not prevent the key from being discarded by the garbage collector, that is, made finalizable, finalized, and then reclaimed. When a key has been discarded its entry is effectively removed from the map, so this class behaves somewhat differently than other Map implementations. – Subin Sebastian Jan 04 '13 at 05:44
  • It should be a WeakHashMap unless you intend to keep the objects around until deliberately removed from the Map. – Patricia Shanahan Jan 04 '13 at 05:44
  • 1
    @Subin Why not just use `map.containsKey(s);`? – Daniel Kaplan Jan 04 '13 at 05:44
  • So i think WeakHashMap makes better fit here – Subin Sebastian Jan 04 '13 at 05:44
  • Ok, thanks a lot. It seems fairly obvious now that I'm looking at it. – roundar Jan 04 '13 at 05:49
  • 1
    @roundar Be aware that this isn't really the Singleton pattern anymore. – Daniel Kaplan Jan 04 '13 at 05:50
  • yes it is more like a Factory pattern as @DanielKaplan s answer says. – Subin Sebastian Jan 04 '13 at 05:52
  • It wouldn't be the Flyweight Pattern as [Bohemian's Answer](http://stackoverflow.com/a/14151683/1907998) suggests? – roundar Jan 04 '13 at 05:56
  • :-) I am not sure , I feel like both apply in this case. – Subin Sebastian Jan 04 '13 at 05:57
  • MyImmutableClass wont qualify as a Flyweight, as there should be sharing of data with other MyImmutableClass objects. A flyweight is an object that minimizes memory use by sharing as much data as possible with other similar objects. http://en.wikipedia.org/wiki/Flyweight_pattern – Subin Sebastian Jan 04 '13 at 06:05
  • So this is a single instance of equivalent objects, where a flyweight would be multiple instances sharing the same (in this case) string field? – roundar Jan 04 '13 at 06:07
  • @roundar I have to say I am not qualified/experienced to answer that. Reading about it almost convinced me it is more similar to a factory than flyweight – Subin Sebastian Jan 04 '13 at 06:08
  • In the above wikipedia link , check out the java example . It is almost similar – Subin Sebastian Jan 04 '13 at 06:12
  • More I read I about it I feel like this is FlyWeight pattern :) – Subin Sebastian Jan 04 '13 at 06:18
1

I think what you're looking for is the Static Factory Pattern, not the Singleton pattern. There's lots of examples of this in the Java classes themselves. For example, if you call the method Integer.valueOf(myString); it may be doing something similar. If you pass in "1" over and over again, it may return the same Integer object every time.

Community
  • 1
  • 1
Daniel Kaplan
  • 62,768
  • 50
  • 234
  • 356
  • yup. just store a map of all the instances by that unique value as key and either build a new instance (and store it in the map) or fetch one from the map. – radai Jan 04 '13 at 05:38
  • I don't agree. It looks more like a registration process for retrieving named `MyImmutableClass` instances. It's not the Factory Pattern. – Robert Harvey Jan 04 '13 at 05:38
  • @RobertHarvey I've edited my answer to add more detail. In a sense that's what `Integer.valueOf()` does. – Daniel Kaplan Jan 04 '13 at 05:43
  • 1
    Read the Wikipedia description for the Factory Pattern. It says *"Define an interface for creating an object, but let the classes that implement the interface decide which class to instantiate.* That's not what's happening here at all. It's several instances of the exact same object; there's no decision making process here on *which type* is being instantiated. – Robert Harvey Jan 04 '13 at 05:58
  • I stand corrected. What I should have said is, "you're looking for the [Static Factory](http://stackoverflow.com/a/4211307/61624)" I'll edit my answer. – Daniel Kaplan Jan 04 '13 at 06:08
1

This is called the flyweight pattern.

The simplest implementation is to:

  • implement hashCode() and equals() that agree
  • use a Map of your key to your class to determine if you've already got one and to store the instances
Bohemian
  • 412,405
  • 93
  • 575
  • 722
0

You would need to keep e.g. a Set containing the objects you might reuse. The main complication is that, if it were done naively, you would prevent garbage collection.

Consider using a WeakHashMap so that your references can be dropped automatically.

In the case you give, you would map a String to the object.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75