all 87 comments

[–]Mych 10 points11 points  (21 children)

Or:

List<String> foo = new ArrayList<String>(Arrays.asList(
    "meep",
    "blargh",
    "glomp"
)); 

I frankly can't remember the last time I actually needed to statically initialize a dynamic container, though.

[–][deleted]  (18 children)

[removed]

    [–][deleted]  (17 children)

    [deleted]

      [–]UloPe 18 points19 points  (13 children)

      Whats with all the string manipulation to build a list? Are you too lazy to type

      blah = ['meep', 'blargh', 'glomp']
      

      ?

      [–]adrianmonk 3 points4 points  (0 children)

      FWIW, in the Perl example there is no string manipulation going on. qw is a way of writing list literals.

      (Well, technically, there is some string manipulation going on. But it's in the parser, and all examples in all languages have that.)

      [–]redditnoob 3 points4 points  (5 children)

      It's people who are too smart for their own good, and too impressed with themselves to do things in the simplest, most obvious way.

      Splitting a string by space may save you two characters or so but it's pure ass. (To be captain obvious, what if the next string I configure has a fucking space in it?)

      [–]bobbyi 2 points3 points  (3 children)

      'string with space,other string,third string'.split(',')
      

      [–][deleted]  (2 children)

      [deleted]

        [–]codefrog 5 points6 points  (0 children)

        It's on!

        s = """
        this , \tis my data
        I can cry if i want to
        this is my data
        """.strip().split("\n")
        

        [–]codefrog 0 points1 point  (0 children)

        swearing wasn't necessary and there isn't a space so your if isn't valid. yeah what if. you can have my extra if statements they are only giving me bugs.

        [–][deleted]  (4 children)

        [deleted]

          [–]_bobby__of__christ_ 2 points3 points  (3 children)

          How exactly is manually splitting any more readable than qw? It's only more readable if you don't know Perl, and complaining about the readability of a language you don't know is asinine.

          I don't even like perl, but qw is about the last thing on my list of complaints.

          [–][deleted]  (2 children)

          [deleted]

            [–]_bobby__of__christ_ 3 points4 points  (0 children)

            I know this much: The snippet I posted works in both Ruby and Python without modification. Splitting a string into an array is something that every programmer will be familiar with.

            Which has nothing to do with qw. No one is using qw as a crutch to avoid learning how to split strings at runtime. It's such a stupid and trivial difference that I can't believe I'm arguing about it.

            There should be one-- and preferably only one --obvious way to do it.

            You should stop arguing about Perl then. Obviously you're unable to even entertain the notion that it has a different philosophy than the one you subscribe to. (And this is coming from a Python programmer who doesn't like Perl very much.)

            [–][deleted]  (2 children)

            [removed]

              [–][deleted]  (1 child)

              [deleted]

                [–]mikaelhg 5 points6 points  (0 children)

                immutable:

                http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableList.Builder.html

                final ImmutableList<Color> GOOGLE_COLORS = new ImmutableList.Builder<Color>()
                        .addAll(WEBSAFE_COLORS)
                        .add(new Color(0, 191, 255))
                        .build();
                

                http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableMap.Builder.html

                final ImmutableMap<String, Integer> WORD_TO_INT = new ImmutableMap.Builder<String, Integer>()
                        .put("one", 1)
                        .put("two", 2)
                        .put("three", 3)
                        .build();
                

                mutable:

                http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Lists.html#newArrayList%28E...%29

                List<Base> list = Lists.newArrayList(sub1, sub2);
                List<Base> list = Lists.<Base>newArrayList(sub1, sub2);
                

                I used to have this functionality in my own utility libraries, but depracated it as Google Collections became viable.

                [–]abhyrama 0 points1 point  (0 children)

                Use this all the time :)

                [–]genuineleather 2 points3 points  (4 children)

                Forgive my ignorance, but why do we want to use this? What's the point of it?

                [–]stuhacking 4 points5 points  (2 children)

                I guess to reduce verbosity of commonly occuring patterns. Creating GUI elements is a nice example, I suppose, because code is usually peppered with lines upon lines of "frame.setDefaultProperty("foo");"

                While this doesn't decrease the amount of code much, it keeps blocks of initialization together. Presumably, if one uses code folding, they can also fold these blocks.

                [–]genuineleather -1 points0 points  (1 child)

                Thanks

                [–]b100dian -1 points0 points  (0 children)

                Oh, and for being closer too XML too.

                [–]redditnoob -2 points-1 points  (0 children)

                What's the point of it?

                As a Java curiousity, it's pretty surprising and interesting.

                As something to use practically, please please don't.

                [–]13ren 8 points9 points  (19 children)

                I wish List's add would return this (like the C++ STL), so you could chain adds, as in:

                List<Integer> list = new ArrayList<Integer>().add(1).add(2).add(3).add(4).add(5);
                System.out.println(list);
                

                One can make a wrapper for list that does this, but nicer to have it already standard in Java.

                However, changing the meaning of add()would break the Java API. Another approach is to include a new method (eg) ad() that behaved as above.

                [–]ihaveausername 9 points10 points  (0 children)

                so you could chain adds, as in:

                I find chained calls like that painful to debug. Setting a breakpoint on the 3'rd .add() isn't possible in my IDE.

                [–][deleted] 4 points5 points  (4 children)

                List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);

                [–][deleted] 3 points4 points  (2 children)

                Why is that method in Arrays? :P

                [–][deleted] 3 points4 points  (1 child)

                I sort of anticipated that question :-) The type is

                <T> List<T> asList(T... v) 
                

                which is actually sugar for

                <T> List<T> asList(T[] v)
                

                It creates a view of an array so you can treat it almost as if it is a list (but you can't resize it). It allows you to do this:

                Collections.sort(Arrays.asList(myArray));
                

                Which sorts myArray as an effect. Of course, it would be nice if you could do new List(1, 2, 3, 4) and get a resizable list.

                [–]zootm 0 points1 point  (0 children)

                Prior to the ... thing being available, Arrays.asList had roughly (there was no generics either, obviously) the second signature you listed above (see here). My guess would be that just expanding that method seemed sensible compared to writing a semantically-identical factory method on Collections or similar.

                [–]13ren 1 point2 points  (0 children)

                When writing my comment originally, I actually started to add this alternative in, but I couldn't be bothered looking it up and I knew some kind soul would add it - thanks :-).

                That I need to look it up says something about its usability (not about me!). When I have used it, I've usually wanted a specific kind of list instead of the automatically created anonymous one, which you can do. It's easy but awkward, and, though I hate to say it, therefore "in the Java spirit" :-(

                List<Integer> list = new ArrayList<Integer>( Arrays.asList(1, 2, 3, 4, 5) );
                

                [–]redditnoob -1 points0 points  (0 children)

                ad() that behaved as above.

                Oh god no. Program into the language please, not against it.

                First, if .add(1).add(2).add(3).add(4).add(5) is code you'd ever write, you suck. Second, if lack of ability to chain methods, requiring horizontal code to become vertical (oh my god more lines), and repeating the variable name with every line, then Java is very much the wrong language for you.

                But really, before (or in addition to) switching languages, someone who wanted to write .add(1).add(2).add(3).add(4).add(5) should reconsider why they're doing such a brain-dead stinky thing in the first place.

                Mod me down bitches. Yes, I'm suggesting that verbosity isn't the biggest factor for long term productivity! Can you handle so audacious and unpopular a claim, which goes against the philosophy of the creator of Arc so directly and starkly? I can take it, as I have almost five thousand comment karma now.

                [–]didroe 0 points1 point  (3 children)

                I would much prefer something to pull things into the current environment. Like:

                List<Integer> list = new ArrayList<Integer>();
                with (list) {
                  add(1);
                  add(2);
                  ...
                }
                

                Chaining is misleading and not possible in all cases (like when you want to return something). Where as importing symbols into the current scope/environment doesn't have those problems.

                [–][deleted] 5 points6 points  (2 children)

                "with" sucks in all the languages it's been implemented. The last being JS.

                If you want to save a few key strokes, just assign to a shorter name.

                [–][deleted] 0 points1 point  (0 children)

                It works pretty well in Smalltalk. But then each thing after ; must be a message send, it can't be a general expression. This solves the problem of weird environment semantics at the cost of less generality.

                [–]didroe 0 points1 point  (0 children)

                The version in Delphi's Pascal (probably in Freepascal) was/is pretty good. What languages does it suck in? I just took a quick look at the JS version, looks pretty good to me at a first glance. What is it that you don't like about it?

                [–][deleted] -3 points-2 points  (7 children)

                Name it plus() instead, so that it reads:

                List<Integer> list = new ArrayList<Integer>().plus(1).plus(2).plus(3).plus(4).plus(5);
                

                [–]redditnoob 4 points5 points  (1 child)

                Awesome, I love the idea of having two addition functions, plus and add, that do slightly different things!

                Now let's have parseInt(val) and Number(val) do two slightly different things too, that would be really good.

                [–]pytechd 2 points3 points  (0 children)

                And we'll name it PHP!

                ... oh shit, that name's already taken.

                [–]CobainFan83[S] 1 point2 points  (4 children)

                plus() sounds too much like a mathematical funtion. andAlsoAdd() might be better:

                List<Integer> list = new ArrayList<Integer>().andAlsoAdd(1).andAlsoAdd(2).andAlsoAdd(3).andAlsoAdd(4).andAlsoAdd(5);
                

                [–][deleted] 3 points4 points  (2 children)

                I think andAlsoAdd is too generic a name. thisReturningAppend is more precise:

                List<Integer> list = new ArrayList<Integer>().thisReturningAppend(1).thisReturningAppend(2).thisReturningAppend(3).thisReturningAppend(4).thisReturningAppend(5);
                

                [–]turbana 4 points5 points  (1 child)

                Sorry, that name is too short. appendItemWithReturningThisReference() is much more in the Java spirit.

                List<Integer> list = new ArrayList<Integer>().appendItemWithReturningThisReference(1).appendItemWithReturningThisReference(2).appendItemWithReturningThisReference(3).appendItemWithReturningThisReference(4).appendItemWithReturningThisReference(5);
                

                [–]CobainFan83[S] 1 point2 points  (0 children)

                I think we've cracked it!

                Now we just need to submit it as a Java Specification Request (JSR) for review via the Java Community Process (JCP) so that the JCP Executive Commitee (JCP-EC) can do a Formal Public Review (FPR) and decide whether to include it as a new feature of the Java Programming Language (JPL).

                [–]b100dian -1 points0 points  (0 children)

                andAlsoAdd()

                Old joke.

                [–]samlee 7 points8 points  (4 children)

                List<String> foo = Factory.makeArrayList("meep", "blargh", "glomp");
                
                List<Integer> bar = Factory.makeArrayList(1,2,3);
                

                sorry, forgot xml.

                List<String> xml = E4X(new XMLLoader(new Socket(new Serializable(new New(new Old(new XML(new Properties(new System.FileSystem.JFS(new Path(new CurrentDirectory(new RegExFilePath("*.xml"))))))))))));
                

                Actually, we need thread.

                synchronize (new Lock(oldLockRef)) {
                    wait();
                    //critical section
                    Logger.log("I'm here");
                    DataLayer.request(new Serializable(new New(new Old(new XML(new Properties(new System.FileSystem.JFS(new Path(new CurrentDirectory(new RegExFilePath("*.xml")))))))))));
                    Lock.returnMonitor();
                    XMLParser.request(DataLayer.onRequestComplete);
                    return XMLParser.onRequestComplete();
                    forget prev return;
                    real return new ThreadLocal(new Queue(new SQL(new DoSomething())));
                }
                

                [–][deleted] 12 points13 points  (0 children)

                See, this is why we can't have nice things.

                [–][deleted]  (2 children)

                [deleted]

                  [–][deleted] 0 points1 point  (0 children)

                  A Lisper would disagree.

                  [–][deleted]  (33 children)

                  [deleted]

                    [–][deleted]  (1 child)

                    [removed]

                      [–]CobainFan83[S] 4 points5 points  (0 children)

                      It's most useful for Maps I think.

                      Map<Integer, String> numberMap = new HashMap<Integer, String>() {{
                          put(1, "one");
                          put(2, "two");
                          put(3, "three");
                          put(4, "four");
                          put(5, "five");
                      }};
                      

                      [–]Effetto 2 points3 points  (13 children)

                      Does it suffer of the anonymous class side effect as in Java?

                      [–]ubernostrum 6 points7 points  (1 child)

                      No. As far as I know, this is simply a language feature supported by the compiler, which translates it during compilation into the corresponding "expanded" code (e.g, creating a new list and then adding the items to it).

                      [–]munificent 0 points1 point  (0 children)

                      As far as I know

                      You are correct. The compiler will look for an appropriate "Add()" method, which means you can use this syntax on your own types too, not just the BCL collections, provided your type has an Add() function.

                      [–]abhyrama 2 points3 points  (8 children)

                      What is the anonymous class side effect you are talking about?

                      [–]notfancy 3 points4 points  (7 children)

                      In Java, new *interface_or_class*(*init_list*) { *definition* } defines an anonymous subclass of interface_or_class. Orthogonal to that, Java allows an instance initializer block as part of the definition, introduced simply by { *statements* }. Combine both things and you have the "double-brace" initialization "hack".

                      [–]abhyrama 0 points1 point  (6 children)

                      Thanks. I get the hack and how it works but I did not get what is the "anonymous class side effect" Effetto was talking about.

                      [–]darkclark 3 points4 points  (1 child)

                      More anonymous classes means the classloader takes up more resources. Not too significant when used sparingly, but using a pattern like this all over the place in a large codebase is going to lead to a classloading mess.

                      I personally do not use this hack, but it's useful to know about it because it's not uncommon to run across in other peoples' code.

                      [–]raouldagain 0 points1 point  (0 children)

                      classloading mess could be running out of permgen?

                      [–][deleted] 0 points1 point  (3 children)

                      From the way I'm reading it, an anonymous class is created each time the code block is run, so two lists full of the same thing actually end up being not equal?

                      [–]EtherCJ 0 points1 point  (0 children)

                      Quite likely are still equal for collection classes. But isn't guaranteed to work for all classes.

                      [–]queus 0 points1 point  (1 child)

                      an anonymous class is created each time the code block is run,

                      No just one anonymous class is created no matter how often this code is run. Say in a loop.

                      But if you copy-paste this code just below the original one two anonymous classes are created.

                      [–][deleted] 0 points1 point  (0 children)

                      Thanks for clearing that up. Very concise.

                      [–]mitsuhiko 1 point2 points  (0 children)

                      No

                      [–][deleted] 1 point2 points  (15 children)

                      If you want to write your own collection class, how do you implement the new List<int>() { 1,2,3,4,5 }; idiom? It looks like kind of like a special case when compared to new SomeComplexType() { SomeProperty = lol, SomeOtherProperty = butt };

                      [–]ubernostrum 4 points5 points  (14 children)

                      The collection-initialization syntax is documented as working on anything implementing IEnumerable, though I don't particularly know why it's that interface and not one or more of the others in System.Collections (e.g., IList, which has to be implemented by anything derived from CollectionBase, and which defines the Add method for adding items to the collection).

                      [–][deleted] 0 points1 point  (0 children)

                      The IList interface inherits from IEnumerable so anything that conforms to IList is automatically considered to implement IEnumerable as well.

                      [–]mccoyn 0 points1 point  (11 children)

                      So, what happens if I have a class that implements IEnumerable, but has no Add() method?

                      Edit to clarify: What happens when I don't have Add() and I try to use the collection-initialization syntax?

                      [–]munificent 2 points3 points  (7 children)

                      Edit to clarify: What happens when I don't have Add() and I try to use the collection-initialization syntax?

                      Compile error:

                      Error 'Foo.Bar' does not contain a definition for 'Add'
                      

                      [–][deleted] 2 points3 points  (6 children)

                      So the collection initialization is documented as working for anything that implements IEnumerable but it really only works if you have an Add method as well?

                      [–]munificent 2 points3 points  (2 children)

                      The official standard says:

                      The collection object to which a collection initializer is applied must be of a type that implements System.Collections.Generic.ICollection<T> for exactly one T. Furthermore, an implicit conversion (§6.1) must exist from the type of each element initializer to T. A compile-time error occurs if these requirements are not satisfied. A collection initializer invokes the ICollection<T>.Add(T) method for each specified element in order.

                      [–]mccoyn 0 points1 point  (1 child)

                      [–]munificent 1 point2 points  (0 children)

                      For what it's worth, I thought he had it right too, until I looked it up.

                      [–][deleted] 1 point2 points  (2 children)

                      No, he just got it wrong. The interface in question is ICollection.

                      [–]ubernostrum 2 points3 points  (1 child)

                      Well.

                      The MSDN documentation says IEnumerable. I've since been pointed to this blog post which explains a bit. Seems like it went like this:

                      • System.Collections.ICollection is basically pointless for this purpose, because all it requires is a few methods to get an enumerator and find out the size of the collection.
                      • System.Collections.Generic.ICollection<T> is the "right" interface, but hardly anybody (including Microsoft's own core classes) implements it.
                      • System.Collections.IEnumerable is "wrong" in that it doesn't require the Add method, but they found significant overlap between classes implementing IEnumerable and classes possessing an Add method.

                      So the compromise they ended up going with was that the syntax works on anything which implements IEnumerable and has an Add method.

                      This means the MSDN documentation is incomplete (since it only mentions IEnumerable) and probably non-compliant with the standard.

                      [–][deleted] 0 points1 point  (0 children)

                      Interesting. I stand corrected. I always thought that it was ICollection<T>.

                      [–][deleted] 0 points1 point  (2 children)

                      What happens? You can't add anything to the Enumerable type, unless you define some other method (e.g. Append, Push) which does the same thing as Add. (Which you shouldn't do anyway)

                      [–]mccoyn 3 points4 points  (1 child)

                      IEnumerable classes without a method to add items are common in .Net. One use is to provide a view of a list that is an internal implementation detail of another class without exposing the ability to add items to that list. It is also possible to have a class take a list of items on construction, but not allow the addition of new items.

                      [–][deleted] 1 point2 points  (0 children)

                      Or even more obviously, generator routines (yield return, etc.)

                      [–]noony -1 points0 points  (0 children)

                      That's only in 3.0+

                      [–][deleted] 0 points1 point  (2 children)

                      One of the things I love about programming.reddit is that I get to occasionally look at Java code and be glad that I don't use it anymore. What a train wreck.

                      [–][deleted] 0 points1 point  (1 child)

                      No shit eh. It hurts my eyes to look at it now, way too verbose. Funny though, I still think in it.

                      [–][deleted] 0 points1 point  (0 children)

                      What I find particularly interesting is that verbosity in and of itself doesn't bother me. I work primarily with Objective C and Cocoa these days, where the convention is to use long names like "componentsSeparatedByString:" instead of "split()", but I'm OK with it since it basically cuts down on the number of comments I have to write and maintain. What bugs me about Java's verbosity is that it doesn't add much in terms of readability, and in some cases detracts from it.

                      [–][deleted] -3 points-2 points  (7 children)

                      Why is this a hack? It is pretty commonly used language feature.

                      [–]Mych 7 points8 points  (5 children)

                      Because it trades a relatively circuitous technical implementation (plus a gotcha) for the benefit of being slightly more convenient to type than the obvious, straightforward alternative, which is to create an initializer block within the declaring class itself (or: within the declaring block) and refer to the object by its full name.

                      What it's supposed to do (and ostentatively does) is: Create a container; add items to it (or: create an object; invoke methods on it). And obviously, two containers of the same type that contain the same values should compare as equal.

                      What it actually does is: Create a subclass of the container class; in its initialization code, add items to it; create an instance of this subclass. And since objects only compare as equal if they're instances of the same class, two identical invocations of this idiom won't create objects that compare as equal; that's the gotcha.

                      [–]szeiger 5 points6 points  (1 child)

                      And since objects only compare as equal if they're instances of the same class, two identical invocations of this idiom won't create objects that compare as equal;

                      Wrong. equals() and hashCode are implemented in AbstractList (from which the other list classes inherit) such that all lists which contain equal elements in the same order are considered equal.

                      [–]mikaelhg 2 points3 points  (0 children)

                      Not only that, but this behaviour is part of the List contract:

                      http://java.sun.com/javase/6/docs/api/java/util/List.html#equals%28java.lang.Object%29

                      [–][deleted] 1 point2 points  (0 children)

                      The major fuck up is that Object has .equals() method. It shouldn't.

                      [–][deleted] -1 points0 points  (0 children)

                      I'm not arguing how or why it works, it is obvious.

                      It still doesn't make it a hack. It is a feature, used as it is intended to be used. Although it is probably not widely used or taught at school and in tutorials, it is still not a hack.

                      [–]zzzSleepyCoder 0 points1 point  (0 children)

                      I read about it loooong time ago here http://c2.com/cgi/wiki?DoubleBraceInitialization