1

Given the following list, how would I approach iteratively adding elements of type FactoryWithArgs with arguments 0 - 100, while still keeping this code in (essentially) one line?

final List<Factory> list = new ArrayList<Factory>(Arrays.asList(
        new Factory0(), new Factory1(), new Factory2(), 
        new FactoryWithArgs(0), new FactoryWithArgs(1), ... ,
        new FactoryWithArgs(99), new FactoryWithArgs(100),
        new Factory4(), new Factory5()));
2
  • Why don't you use loop? Commented Aug 4, 2015 at 16:45
  • It's mainly a readability thing, I want to visually see all the factories in list as the list is initialized... it's just a personal preference. My question is, can you even use a loop? Commented Aug 4, 2015 at 16:47

2 Answers 2

2

Due to @Brian comment on "double brace" initialization being a no no, here's another suggestion.

For the FactoryWithArgs class I would make a FactoryWithArgsMaker class that is designed to make FactoryWithArgs objects as a List.

Something like:

public static class FactoryWithArgsMaker {
    public static List<FactoryWithArgs> makeNew(int start, int end) {
        List<FactoryWithArgs> list = new ArrayList();
        for (int i = 0; i <= end; i++) {
            list.add(new FactoryWithArgs(i));
        }
        return list;
    }
}

As long as the order of your "Factories" don't matter in your list, and with Java 8 Streams you can initialize your list in one line like this:

List<Factory> list = Stream.concat(
    Arrays.asList(
        new Factory0(), new Factory1(), new Factory2(), 
        new Factory3(), new Factory4(), new Factory5()
    ).stream(),
    FactoryWithArgsMaker.makeNew(0, 100).stream()
).collect(Collectors.toList());

The Stream.concat() takes the contents of Arrays.asList() and the List<FactoryWithArgs>, returned from FactoryWithArgsMaker.makeNew(), and combines them into a single stream which we then convert back into a List (.collect(Collectors.toList());

Sign up to request clarification or add additional context in comments.

2 Comments

Never do this. This creates an anonymous inner class and the code is being executed before the constructor you're calling itself. An instance is bound to the parent object and thus, even if no reference to the parent object exists anymore, references to the object of the anonymous inner class will keep it alive (indirectly). This can cause memory leaks. Never ever use {{}}. It's the worst idea somebody came up with (although it looks cool).
Much better. :) I like the stream approach. And btw: You can keep the order of the objects by splitting the Arrays.asList(...) statement into two (0..2, ...makeNew(0, 100), 3..5), because the .stream() call creates a sequential stream.
0
    final List<Factory> list = new ArrayList<Factory>();        
    list.add(new Factory0());
    list.add(new Factory1());
    list.add(new Factory2());
    for (int i = 0; i < 101; i++) {
        list.add(new FactoryWithArgs(i));
    }
    list.add(new Factory4());
    list.add(new Factory5());

You can put it in a method, if you prefer.

3 Comments

I want to do this in one line, most likely using Arrays.asList.
I think, it's possible only if you write by hand all 106 objects you want to add
@budi you could use a static method with the loop as initializer. Or you can use a static block ({ for (...) {...} }) right below the list declaration as macara suggests.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.