Is language support for collections is a coin feature ?

Kevin Lee kevin at lckymn.com
Mon Sep 27 11:42:43 PDT 2010


> Why not? :
>
> User user = new UserBuilder() {{
>     firstName = "Remi";
>     lastName = "Forax";
 >     addresses = new Address[] {
 >         new AddressBuilder() {{
>             zipCode = "30785";
>         }},
>         new AddressBuilder() {{
>             zipCode = "67899";
>         }}
>     };
> }}.build();

You're adding AddressBuilder objects to an Address array. If Reinier didn't
make any mistake the code probably be like

User user = new User.UserBuilder()
{{
    firstName = "Kevin";
     lastName = "Lee";
    addresses.add(new AddressBuilder(){{ zipCode = "12345"; }},
                  new AddressBuilder(){{ zipCode = "111111"; }});
}}.build();

It probably has AddressesBuilder to build a list of Address objects.
public class AddressesBuilder implements GenericBuilder<List<Address>>
{
    private List<Address> addressList = new ArrayList<Address>();

    public void add(AddressBuilder... addressBuilders)
    {
        for (AddressBuilder addressBuilder : addressBuilders)
            addressList.add(addressBuilder.build());
    }

    @Override
    public List<Address> build()
    {
        return Collections.unmodifiableList(addressList);
     }
}

public class User
{
    private final String firstName;
    private final String lastName;
    private final List<Address> addresses;

    public static class UserBuilder implements GenericBuilder<User>
     {
        public String firstName;
        public String lastName;
        public AddressesBuilder addresses = new AddressesBuilder();

        @Override
        public User build()
        {
            return new User(this);
        }
    }

    private User(UserBuilder builder)
    {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.addresses = builder.addresses.build();
    }

    // getters are omitted.
}


I think it can be just like

User user = new User.UserBuilder()
{{
    firstName = "Kevin";
    lastName = "Lee";
    addresses(new AddressBuilder(){{ zipCode = "12345"; }},
               new AddressBuilder(){{ zipCode = "111111"; }});
}}.build();

if UserBuilder is changed to
    public static class UserBuilder implements GenericBuilder<User>
    {
        public String firstName;
        public String lastName;
        private List<Address> addresses = new ArrayList<Address>();

        public void *addresses*(AddressBuilder... addressBuilders)
        {
            for (AddressBuilder addressBuilder : addressBuilders)
                 addresses.add(addressBuilder.build());
        }

        @Override
        public User build()
        {
            return new User(this);
        }
    }
and the constructor of User would be
    private User(UserBuilder builder)
    {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.addresses = Collections.unmodifiableList(builder.addresses);
    }

Then it doesn't need an additional builder that is Address*es*Builder.


Or it can just use the Arrays.asList() method.

User user = new User.UserBuilder()
{{
    firstName = "Kevin";
     lastName = "Lee";
    addresses = Arrays.asList(new AddressBuilder(){{ zipCode = "12345";
}}.build(),
                              new AddressBuilder(){{ zipCode = "111111";
}}.build());
}}.build();

and UserBuilder would be simpler
    public static class UserBuilder implements GenericBuilder<User>
    {
        public String firstName;
        public String lastName;
        public List<Address> addresses;

        @Override
        public User build()
        {
            return new User(this);
        }
    }

Anyway, although that would be a good way to create an (immutable) object
especially because Java does not have Named Parameter (
http://en.wikipedia.org/wiki/Named_parameter), I prefer using Builder
Pattern to using double brace initialisation (using Instance Initializer) as
this creates a new class per each use.

I don't know why the matter of collections literals has become a matter of
properties nor am I sure if introducing properties is a good idea, because I
like to use a method with a meaningful name. For instance, if I want to cut
down the price of a product, I don't want to do like
 product.price - 10;
but
product.cutDownPrice(10);

It's probably just me who doesn't like properties but I'm a flip-flopper so
I would perhaps one day like it. :)

So will 'Language support for collections' be included in JDK8 or not?

By the way, is there any possibility that a future Java will have Named
Parameter?


On 26/09/10 22:39, Ulf Zibis wrote:
>
>  Am 26.09.2010 05:51, schrieb Reinier Zwitserloot:
> > Advocate of the devil mode:
> >
> > User user = new User()
> >      .firstName("Remi")
> >      .lastName("Forax")
> >      .addAddress().zipCode("30785").done()
> >      .address(new Address().zipCode("30785"));
>
> See also:
> http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001180.html
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6479372
>
> > User user = new UserBuilder() {{
> >      firstName = "Remi";
> >      lastName = "Forax";
> >      addresses.add(
> >          new AddressBuilder() {{
> >              zipCode = "30785";
> >          }},
> >          new AddressBuilder() {{
> >              zipCode = "67899";
> >          }});
> > }}.build();
> >
>
> Why not? :
>
> User user = new UserBuilder() {{
>     firstName = "Remi";
>     lastName = "Forax";
>      addresses = new Address[] {
>          new AddressBuilder() {{
>             zipCode = "30785";
>         }},
>         new AddressBuilder() {{
>             zipCode = "67899";
>         }}
>     };
> }}.build();
>
>
> -Ulf
>



More information about the coin-dev mailing list