0

Well confusing title, to put it longer but simpler, can you create an object class, in which a constructor will create multiple of the objects of the class and store them in an static object arrayList, all this in one class? If you can't can you make a static void in that class to do so?

Regards Augustas

Monad
  • 680
  • 8
  • 15
  • 3
    Since this is a yes/no q/a I would say: Yes. – Luiggi Mendoza Sep 10 '14 at 22:17
  • 3
    It doesn't matter if you could do this, you shouldn't. You wouldn't want to do this as it would lead to fragile and confusing code since it changes the job of a constructor -- that being to create a single instance of an object. Why not simply create some factory method to do this? Why this confusing XY problem type plan? – Hovercraft Full Of Eels Sep 10 '14 at 22:19
  • Use a Factory Method to do this. – Robert Harvey Sep 10 '14 at 22:21
  • Yes. But instead of doing it a constructor you might consider a static method to create the instances. It can check state so you don't have multiple created. – JustinKSU Sep 10 '14 at 22:21
  • You can make a constructor do many things *as a side-effect*, but canonically a constructor only creates one object, and it returns it without storing it anywhere. – Hot Licks Sep 10 '14 at 22:22
  • Seems like you want to keep low memory and reuse your objects. If so, implement [Flyweight pattern](http://en.wikipedia.org/wiki/Flyweight_pattern). But note that this is not the same as what you're describing here. – Luiggi Mendoza Sep 10 '14 at 22:23
  • Use a [static factory method](http://stackoverflow.com/a/929273/2398375). This will allow you to call a method that controls the creation of objects, allowing you to create multiple objects in one call. Never create multiple instances of a class using it's constructor. 1 constructor call should == 1 instance of that class – Vince Sep 10 '14 at 22:32

2 Answers2

0

you could do it like this, i'll leave the why to you, but it is generally a good question to ask youself, why am i doing it this way...

import java.util.ArrayList;

public class Static {

public static ArrayList<Foo> foos = new ArrayList<Foo>();

//this initializes your list of objects...
static
{
    foos.add(new Foo("A"));
    foos.add(new Foo("B"));
    foos.add(new Foo("C"));
    foos.add(new Foo("D"));
}
}

class Foo
{
    String value;   
    public Foo(String v) { value = v; }
}
Dave
  • 867
  • 6
  • 11
0

I recommend implementing Flyweight Pattern. From wikipedia:

A flyweight is an object that minimizes memory use by sharing as much data as possible with other similar objects; it is a way to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory.

Java already implements this in Integer class through the static factory method Integer#valueOf method and the internal IntegerCache class that holds by default Integers from -128 til 127. Here's an example:

Integer i1, i2, i3;
i1 = 100; //it will call Integer with value of 100 from cache
i2 = Integer.valueOf(100); //it will call Integer with value of 100 from cache
i3 = new Integer(100); //creates a new instance
System.out.println(i1 == i2); //true
System.out.println(i1 == i3); //false
System.out.println(i1.equals(i2)); //true
System.out.println(i1.equals(i3)); //true

Knowing this, you can create your own flyweight implementation:

public class YourClass {
    private final String name;
    private final String description;
    //more fields...

    //making a private constructor in case you don't want other classes
    //to create instance of this class carelessly
    //like Integer
    private YourClass(String name, String description) {
        this.name = name;
        this.description = description;
        //probably more logic here
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }

    @Override
    public int hashCode() {
        //sample implementation
        //it can be heavily improved
        return name.hashCode();
    }

    @Override
    public boolean equals(Object o) {
        //sample implementation
        //it MUST be heavily improved
        if (o == this) return true;
        if (!(o instanceof YourClass)) return false;
        YourClass other = (YourClass)o;
        return this.name.equals(other.getName());
    }

    //static flyweight manager
    private static class YourClassFlyweight {
        //cache with weak entries
        //wrapped into a synchronized Map
        static final Map<String, YourClass> cache =
            Collections.synchronizedMap(
                new WeakHashMap<String, YourClass>());

        //if you don't want weak entries
        //then just use a ConcurrentHashMap
        //static final Map<String, YourClass> cache =
        //    new ConcurrentHashMap<String, YourClass>()));

        private YourClassFlyweight() { }
    }

    //using Factory Method along with this flyweight implementation
    public static YourClass create(String name, String description) {
        //check if it's not created
        if (YourClassFlyweight.cache.containsKey(name)) {
            //if it is, then return current instance
            return YourClassFlyweight.cache.get(name);
        }
        //otherwise, create the instance and add it into cache
        synchronized(YourClassFlyweight.cache) {
            YourClass newInstance = new YourClass(name, description);
            YourClassFlyweight.cache.put(name, newInstance);
            return newInstance;
        }
    }
}

Basic test for this:

YourClass ins1 = YourClass.create("Luiggi", "Mendoza");
YourClass ins2 = YourClass.create("Luiggi", "OtherLastName");
System.out.println(ins1.equals(ins2)); // true
System.out.println(ins1 == ins2); // unbelievably, true

Also, instead using Map with some implementation for a cache, you may use a real cache library like ehcache instead.

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332