Proposal: Concise Collection Initialization Syntax

Shams Mahmood shams.mahmood at gmail.com
Sun Mar 29 18:07:06 PDT 2009


Concise Collection Initialization Syntax

VERSION
This is version 1.0.

AUTHOR(S):
Shams Mahmood Imam

OVERVIEW

FEATURE SUMMARY:
Collection classes are among the most frequently used in the Java SDK and 
share common features with Arrays. However, unlike arrays Collections do 
not have any additional language features for instantiation and populating (
filling elements into the Collection). This proposal aims to provide these 
Collection citizens of java additional language support to provide a concise 
syntax for populating them during instantiation. 

MAJOR ADVANTAGE:
Will provide a concise syntax to populate Collections during initialization.

MAJOR BENEFIT:
New syntax will lead to fewer lines of code to populate Collections easing 
the use of Collections.

MAJOR DISADVANTAGE:
The language grammar needs to be extended.

ALTERNATIVES:
The comparatively more verbose add/set methods for Collection classes and 
put methods for Maps.

EXAMPLES

SIMPLE EXAMPLE:

public class Main {
  public static void main(String[] arguments) {
    List<String> l1 = new LinkedList<String>()["a", "b", "c" ];
  }
}

ADVANCED EXAMPLE:

public class TestConcise {
  public static void main(String[] args) {
    boolean b = new java.util.LinkedList<String>()
      ["a", "b", "c" ].add("d");
    param(new java.util.ArrayList<String>() {
        public boolean add(String e) {
          return super.add(e);
        }
      } ["a", "b", "c" ]
    );
    java.util.Map<Integer, String> m1 = retMap();
    
    java.util.LinkedList<String> l1 = new
    java.util.LinkedList<String>()["a", "b", "c" ];
  }

  private static void param(
      final java.util.Collection<? extends Object> coll){
    System.out.println(coll);
  }

  private static java.util.Map<Integer, String> retMap() {
    return new java.util.HashMap<Integer, String>() {} 
      [1:"a", 2:"b", ];
  }
}

DETAILS

SPECIFICATION:
Java Language Specification changes:

15.XX Collection Instance Creation Expressions
----------------------------------------------
Collection Instance Creation Expressions are similar to Class Instance Creation 
Expressions except that they can be used to create instances of Collections
only and are followed by a mandatory '[ ArgumentList opt ]'.
e.g. 
java.util.LinkedList<String> l1 = new
    java.util.LinkedList<String>()["a", "b", "c" ];

CollectionInstanceCreationExpression:
  new TypeArguments opt ClassOrInterfaceType ( ArgumentList opt ) ClassBodyopt [ ArgumentList opt ]
  Primary. new TypeArguments opt Identifier TypeArguments opt ( ArgumentList opt ) ClassBodyopt [ ArgumentList opt ]
ArgumentList:
  Expression
  ArgumentList , Expression

15.YY Map Instance Creation Expressions
---------------------------------------
Map Instance Creation Expressions are similar to Class Instance Creation 
Expressions except that they can be used to create instances of Maps
only and are followed by a mandatory '[ MapArgumentList opt ]'. Map argument
List are individually a pair of colon separated expressions.
e.g. 
java.util.Map m1 = new 
    java.util.HashMap<Integer, String>() {} [1:"a", 2:"b", ];

MapInstanceCreationExpression:
  new TypeArguments opt ClassOrInterfaceType ( ArgumentList opt ) ClassBodyopt [ MapArgumentList opt ]
  Primary. new TypeArguments opt Identifier TypeArguments opt ( ArgumentList opt ) ClassBodyopt [ MapArgumentList opt ]
MapArgumentList:
  Expression : Expression
  MapArgumentList , Expression : Expression


15.8 Primary Expressions
original:
---------
  PrimaryNoNewArray:
    Literal
    Type . class
    void . class
    this
    ClassName.this
    ( Expression )
    ClassInstanceCreationExpression
    FieldAccess
    MethodInvocation
    ArrayAccess

replaced with:
--------------
  PrimaryNoNewArray:
    Literal
    Type . class
    void . class
    this
    ClassName.this
    ( Expression )
    ClassInstanceCreationExpression
    CollectionInstanceCreationExpression
    MapInstanceCreationExpression
    FieldAccess
    MethodInvocation
    ArrayAccess



COMPILATION:

After successful creation of the AST handling the additional grammar for 
Collection and Map instantiation expressions, the syntactic sugar will be 
replaced by JDK1.4 compatible code during the Code Generation phase. This 
is consistent with how JDK5.0 constructs like the for-each loop is handled 
by the compiler.

e.g.
public class TestConcise {
  public static void main(String[] args) {
    boolean b = new java.util.LinkedList<String>()
      ["a", "b", "c" ].add("d");
    param(new java.util.ArrayList<String>() {
        public boolean add(String e) {
          return super.add(e);
        }
      } ["a", "b", "c" ]
    );
    java.util.Map<Integer, String> m1 = retMap();
    
    java.util.LinkedList<String> l1 = new
    java.util.LinkedList<String>()["a", "b", "c" ];
  }

  private static void param(
      final java.util.Collection<? extends Object> coll){
    System.out.println(coll);
  }

  private static java.util.Map<Integer, String> retMap() {
    return new java.util.HashMap<Integer, String>() {} 
      [1:"a", 2:"b", ];
  }
}

is converted to:
 
class TestConcise$1 extends java.util.ArrayList {
  TestConcise$1() {
    super();
  }

  public boolean add(String e) {
    return super.add(e);
  }

  /*synthetic*/ public boolean add(Object x0) {
    return this.add((String)x0);
  }
},

class TestConcise$2 extends java.util.HashMap {
  TestConcise$2() {
    super();
  }
},

public class TestConcise {
  public TestConcise() {
    super();
  }

  public static void main(String[] args) {
    boolean b = java.util.CollectionUtil.fillCollection(
      new java.util.LinkedList(), 
      new String[]{"a", "b", "c"}).add("d");
    param(java.util.CollectionUtil.fillCollection(
    new TestConcise$1(), new String[]{"a", "b", "c"}));
    java.util.Map m1 = retMap();
    
    java.util.LinkedList l1 = 
      java.util.CollectionUtil.fillCollection( 
        new java.util.LinkedList(), 
        new String[]{"a", "b", "c"});
  }

  private static void param(
      final java.util.Collection coll) {
    System.out.println(coll);
  }

  private static java.util.Map retMap() {
    return java.util.CollectionUtil.fillMap(
      new TestConcise$2(),
      new Integer[]{Integer.valueOf(1), Integer.valueOf(2)},
      new String[]{"a", "b"});
  }
}


TESTING:

LIBRARY SUPPORT:
Two new utility methods are required to support filling the Collection 
and Map instances with the following signatures:

public static <T extends Object> Collection<T> fillCollection(Collection<T> theCol, T[] theEls);
public static <K extends Object, V extends Object> Map<K, V> fillCollection(Map<K, V> theMap, K[] theKeys, V[] theVals);

The Collections class is a perfect place to add these methods.

REFLECTIVE APIS:
This proposal does not require any reflective API changes. 

OTHER CHANGES:
No changes required.

MIGRATION:
No migration is needed. 

COMPATIBILITY

BREAKING CHANGES:
No breaking changes.

EXISTING PROGRAMS:
Existing programs are not affected by this change.

REFERENCES
My Java7 Wishlist regarding Collections, http://shamsmi.blogspot.com/2008/04/my-java7-wishlist-regarding-collections.html
Implementation of My Java7 Wishlist, http://shamsmi.blogspot.com/2008/05/implementation-of-my-java7-wishlist.html

EXISTING BUGS:
None.

URL FOR PROTOTYPE (optional):
Projects kijaro's concisecollections branch: https://kijaro.dev.java.net/source/browse/kijaro/branches/concisecollections/


      


More information about the coin-dev mailing list