<div dir="ltr">In Python, arrays exist as a lower level library or via third-party libraries like NumPy. Unless you're doing specialized processing, you don't typically work with actually arrays. As with Java, you're normally working with lists.<div>But the syntax in Python for working with lists makes list initialization simple and easy. I would love to see a similar syntax in Java for both List and Map initialization.<br>E.g.,</div><div>```Python</div><div>foo = [{"key": {"subkey": "value"}}] </div><div>```</div><div>The simplest way I can duplicate this in Java is </div><div>```Java</div><div>List<Map<String, Object>> foo = List.of(<br>    Map.of("key", Map.of("subkey", "value"))<br>);</div><div>```</div><div>Now, this doesn't look too bad. In Java this has created an immutable List, which is probably adequte in many cases. In the context of the actual code as a unit test, immutability is fine; but if you needed mutability:</div><div>List<Map<String, Object>> foo = new ArrayList<>();<br>Map<String, Object> outerMap = new HashMap<>();<br>Map<String, String> innerMap = new HashMap<>();<br><br>innerMap.put("subkey", "value");<br>outerMap.put("key", innerMap);<br>foo.add(outerMap);</div><div><br></div><div>And you can see how the boilerplate starts to obscure the nature of the data for more complicated initializations:<br>Python:<br>result [{"key": {"subkey": [{"subsubkey": [{"subsubsubkey": [{"subsubsubsubkey": [1]}]}]}]}}]<br></div><div><br></div><div>Java:<br>List<Map<String, Object>> result = List.of(<br>    Map.of(<br>        "key", Map.of(<br>            "subkey", List.of(<br>                Map.of(<br>                    "subsubkey", List.of(<br>                        Map.of(<br>                            "subsubsubkey", List.of(<br>                                Map.of(<br>                                    "subsubsubsubkey", List.of(1)<br>                                )<br>                            )<br>                        )<br>                    )<br>                )<br>            )<br>        )<br>    )<br>);</div><div><br></div><div>So it would be nice if Java could use [] and {} as syntax for initializing Lists and Maps. I don't think it would be too complicated to add this syntax, e.g.,</div><div><br></div><div>List<Integer> foo = [1, 2, 3]; // clear in context this is initializing a List, not an array.</div><div><br></div><div>or more explicitly:</div><div>List<Integer> foo = new ArrayList<>[1, 2, 3];</div><div><br></div><div>or perhaps</div><div>List<Integer> foo = new ArrayList<>([1, 2, 3]); // and [1,2,3] could be auto-boxed to a Collection object for the existing ArrayList constructor.</div><div><br></div><div>I'm just talking about initialization syntax. The compiler should be able to determine the new syntax from context, just as it can tell the difference in {} between a block of code and an array initializer or anonymous class definition.</div><div><br></div><div>I also could be totally wrong on how "easy" it would be to add this. But I do know it would simplify my unit testing code!</div><div><br></div><div>- Rob</div><div><br></div><div><br></div><div><br></div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Sat, Jul 26, 2025 at 2:49 PM Brian Goetz <<a href="mailto:brian.goetz@oracle.com">brian.goetz@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>

  
  <div>
    All of the points you raise that "arrays are not the abstraction you
    are looking for" are absolutely true -- and well understood. The
    goal of improving array creation is not to help arrays win market
    share away from collections.<br>
    <br>
    But there is a reason that the language has arrays, and that reason
    hasn't gone away.  Arrays are the bottom brick on which the tower of
    better data structures are built.  You can't have ArrayList or
    HashMap without arrays.  Arrays are part of the language for a
    reason.  As we improve the language, sometimes arrays have to
    improve with it.  (For example, if you have a
    non-implicitly-constructible value class NVA (one who has no valid
    default value), and someone wants to create an array of NVA![n],
    allowing the existing "zero the memory" array creation expression to
    create it would undermine the integrity of the runtime by exposing
    objects that are not in a valid state as determined by their
    constructor.  So we can't allow that, which means we have to provide
    something else.)<br>
    <br>
    If we hadn't found the need to improve other aspects of
    initialization, we probably wouldn't have bothered to improve array
    initialization.  But because we are improving initialization more
    broadly, we have to do the whole job.  Not being able to create
    interesting arrays linguistically would forever look like a weird
    omission.  <br>
    <br>
    Your suggestion -- "why not just" not improve array creation
    linguistically, and shunt any sort of exotic array creation to a
    privileged API -- leaves the user with little explanation for why
    the tower stands up.  The bottom brick is not there, instead
    replaced by some sort of magic that seems to hold up the brick above
    it.  While we expect relatively few programmers to program with
    arrays (ideally, just the guy who maintains ArrayList and HashMap,
    and the like), we should provide linguistic mechanisms for properly
    using core linguistic building blocks.  <br>
    <br>
    I can imagine three implicit lines of thought for why you think such
    a low-level mechanism should be performed by a privileged library
    rather than a language feature: <br>
    <br>
     - The easier we make it to use, the more people will use it, and
    you would like fewer people to use it (as would we.)  A
    scary-looking library will scare away more people than a
    pretty-looking language feature.<br>
     - Language features are expensive, more expensive than libraries,
    so by shunting this to a library, we preserve resources to focus on
    more important things.  <br>
     - Array initialization appears to be competing for resources with
    features like collection literals, and you'd rather have the latter,
    so suggesting that we skip the former seems like it would bring the
    latter more quickly.  <br>
    <br>
    These are appealing-sounding arguments, but they don't point to
    either usability wins or project-management wins.  Arrays are the
    right tool for some jobs.  Collections are the right tool for others
    (most others.)  But the way to encourage people to use the right
    tool is not to make the other tools harder to use.  (We too would
    like to have linguistic support for creating sets, lists, maps, etc,
    but that feature is not competing with arrays, its waiting for
    something else.)  Nor is the cost of a privileged array-construction
    API significantly cheaper than a language feature.  <br>
    <br>
    Cheers,<br>
    -Brian<br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <div>On 7/26/2025 5:03 PM, david Grajales
      wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="ltr">
        <div dir="ltr">
          <div dir="ltr">
            <div dir="ltr">
              <div dir="ltr">
                <p>Dear Amber developers,</p>
                <p>I recently watched the JavaONE 2025 session titled <em>“A
                    New Model for Java Object Initialization”</em> and
                  was particularly intrigued by the proposed
                  improvements to array initialization.</p>
                <p><a href="https://www.youtube.com/watch?v=XtvR4kqK8lo" target="_blank">https://www.youtube.com/watch?v=XtvR4kqK8lo</a></p>
                <p><br>
                </p>
                <p>I strongly agree that Java needs better mechanisms
                  for initializing data structures in a concise,
                  expressive, and stricter manner—similar in spirit to
                  Python’s list comprehensions and aligned with Strict
                  initialization, required for Valhalla. Such constructs
                  can help avoid subtle bugs and the presence of
                  unintended <code>null</code> values. However, I remain
                  skeptical about the decision to focus this new model
                  exclusively around arrays.</p>
                <p>As has been discussed over the past few months,
                  arrays are not ideal as a default abstraction,
                  especially for students or in enterprise applications.
                  Arrays are a low-level construct with several
                  limitations:</p>
                <ul>
                  <li>
                    <p>They do not integrate well with generics.</p>
                  </li>
                  <li>
                    <p>They are of fixed size.</p>
                  </li>
                  <li>
                    <p>They lack methods and flexibility.</p>
                  </li>
                  <li>
                    <p>They are syntactically and semantically
                      inconsistent with the rest of the Java Collections
                      Framework.</p>
                  </li>
                </ul>
                <p>In many ways, arrays are a legacy feature inherited
                  from C/C++—much like the original <code>switch</code> statement—that
                  carry forward certain limitations that Java has
                  otherwise worked hard to overcome.</p>
                <p>Given these issues, Why not just create an small API
                  that facilitates the creation of the most used data
                  structures with strict initialization? </p>
                <p>For example:</p>
                <p><br>
                </p>
                <p>void main(){</p>
                <p><br>
                </p>
                <p>    // toArray</p>
                <p>    var array =
                  StrictCollections.toArray(String.class, 5, i ->
                  "Item-" + i);</p>
                <p>    IO.println("Array: " + Arrays.toString(array));</p>
                <p><br>
                </p>
                <p>    // toList</p>
                <p>    var list = StrictCollections.toList(5, i ->
                  "List-" + i);</p>
                <p>    IO.println("List: " + list);</p>
                <p><br>
                </p>
                <p>    // toSet</p>
                <p>    var set = StrictCollections.toSet(5, i ->
                  "Set-" + (i % 3));</p>
                <p>    IO.println("Set: " + set);</p>
                <p><br>
                </p>
                <p><br>
                </p>
                <p>    var map = StrictCollections.toMap(</p>
                <p>        5,</p>
                <p>        i -> "Key-" + i,</p>
                <p>        i -> i * 100</p>
                <p>    );</p>
                <p>    IO.println("Map: " + map);</p>
                <p><br>
                </p>
                <p>   </p>
                <p>}</p>
                <p><br>
                </p>
                <p><br>
                </p>
                <p>public static class StrictCollections {</p>
                <p><br>
                </p>
                <p>    public static <T> T[]
                  toArray(Class<T> clazz, int size,
                  IntFunction<T> function) {</p>
                <p>        @SuppressWarnings("unchecked")</p>
                <p>        T[] array = (T[]) Array.newInstance(clazz,
                  size); // This could be a frozen array once these are
                  ready</p>
                <p>        for (int i = 0; i < size; i++) {</p>
                <p>            array[i] = function.apply(i);</p>
                <p>        }</p>
                <p>        return array;</p>
                <p>    }</p>
                <p><br>
                </p>
                <p>    public static <T> ArrayList<T>
                  toList(int size, IntFunction<T> function) {</p>
                <p>        var list = new ArrayList<T>(size);</p>
                <p>        for (int i = 0; i < size; i++) {</p>
                <p>            list.add(function.apply(i));</p>
                <p>        }</p>
                <p>        return list;</p>
                <p>    }</p>
                <p><br>
                </p>
                <p>    public static <T> HashSet<T>
                  toSet(int size, IntFunction<T> function) {</p>
                <p>        List<T> list = new
                  ArrayList<>(size);</p>
                <p>        for (int i = 0; i < size; i++) {</p>
                <p>            list.add(function.apply(i));</p>
                <p>        }</p>
                <p>        return new HashSet<>(list);</p>
                <p>    }</p>
                <p><br>
                </p>
                <p>    public static <K, V> HashMap<K, V>
                  toMap(int size, IntFunction<K> kFunction,
                  IntFunction<V> vFunction) {</p>
                <p>        HashMap<K, V> map = new
                  HashMap<>(size);</p>
                <p>        for (int i = 0; i < size; i++) {</p>
                <p>            map.put(kFunction.apply(i),
                  vFunction.apply(i));</p>
                <p>        }</p>
                <p>        return map;</p>
                <p>    }</p>
                <p>}</p>
                <p>While this is admittedly a rough sketch developed in
                  just a few minutes, I believe a similar—much more
                  thoroughly designed—approach could provide much
                  greater flexibility with far less complexity than
                  introducing a dedicated array-specific feature. It
                  would also extend naturally to a broader range of use
                  cases --Such as being able to be combined with the
                  Stream API in a much more ergonomic way--.
                  Furthermore, as value classes and parametric JVM start
                  to make it into the language and the JVM, the
                  advantages of arrays and primitive types will diminish
                  further. In that context, arrays will become even less
                  compelling in the future.</p>
                <p>If Java is to introduce a safe, expressive, and
                  idiomatic strict initialization literal for data
                  structures, I would argue it should primarily support <code>List</code>, <code>Set</code>,
                  and <code>Map</code>—especially <code>Map</code>,
                  which remains one of the least ergonomic structures to
                  initialize in the language today, particularly when
                  compared to alternatives in Dart, Python, or even
                  JavaScript objects. Data structures that are much more
                  used.</p>
                <p><br>
                </p>
                <p>Thank you so much for all your work and always yours</p>
                <p><br>
                </p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
  </div>

</blockquote></div>