Статьи

Массив, список, набор, отображение, кортеж, запись литералов в Java

Иногда, когда я в восторге от мощи и выразительности JavaScript, мне не хватает одной или двух функций в мире Java. Помимо лямбда-выражений / замыканий или того, что вы хотите назвать «анонимными функциями», это использование расширенных литералов для распространенных типов данных, таких как массивы, списки, наборы, карты и т. Д. В JavaScript никто не будет думать о создании Постоянная карта вроде этого:

1
2
3
4
var map = new Object();
map["a"] = 1;
map["b"] = 2;
map["c"] = 3;

Вместо этого вы, вероятно, напишите

1
var map = { "a":1, "b":2, "c":3 };

В частности, при передаче сложных параметров в функцию API это оказывается очень удобным синтаксисом.

Как насчет этих вещей в Java?

Недавно я опубликовал информацию об обходном пути, который вы можете использовать для создания «List literal» с помощью Arrays.asList (…) здесь:

http://blog.jooq.org/2011/10/28/javas-arrays-aslist-is-underused/

Это несколько хорошо. Вы также можете создавать массивы при их назначении, используя массивы литералов. Но вы не можете передать литерал массива методу:

01
02
03
04
05
06
07
08
09
10
11
// This will work:
int[] array = { 1, 2, 3 };
 
// This won't:
class Test {
  public void callee(int[] array) {}
  public void caller() {
    // Compilation error here:
    callee({1, 2, 3});
  }
}

Упоминание Брайана Гетца о различных литералах в lambda-dev

Пропустив эту функцию довольно долго, я был очень рад прочитать упоминание Брайана Гетца о них в списке рассылки lambda-dev:

http://mail.openjdk.java.net/pipermail/lambda-dev/2012-May/004979.html

Идеи, которые он перечислял, были следующими:

1
2
3
4
5
6
#[ 1, 2, 3 ]                          // Array, list, set
#{ "foo" : "bar", "blah" : "wooga" // Map literals
#/(\d+)$/                             // Regex
#(a, b)                               // Tuple
#(a: 3, b: 4)                         // Record
#"There are {foo.size()} foos"        // String literal

К сожалению, он также добавил следующий отказ от ответственности:

Не то чтобы мы приняли все это сразу (или когда-либо)

Очевидно, что на данном этапе развития языка Java для Java 8 он не может дать никаких гарантий относительно того, что может быть добавлено в будущем. Но с точки зрения jOOQ идея возможности объявлять кортежи и записывать литералы (с соответствующей поддержкой языков для таких типов!) Весьма волнующая. Представьте, что вы выбираете произвольные кортежи / записи с соответствующими парами индекс / тип, столбец / тип. Представьте себе такую ​​конструкцию в Java или Scala (используя jOOQ):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
// For simplicity, I'm using Scala's val operator here,
// indicating type inference. It's hard to guess what true
// record support in the java language should look like
for (val record : create.select(
                           BOOK.AUTHOR_ID.as("author"),
                           count().as("books"))
                        .from(BOOK)
                        .groupBy(BOOK.AUTHOR_ID)
                        .fetch()) {
   
   // With true record support, you could now formally extract
   // values from the result set being iterated on. In other
   // words, the formal column alias and type is available to
   // the compiler:
   int author = record.author;
   int books = record.books;
}

Очевидно, это всего лишь предположение, но вы можете видеть, что при истинной поддержке кортежей / записей в языке Java во вселенной Java будет реализовано множество функций, что окажет очень сильное влияние на все существующие библиотеки и API.

Будьте на связи!

Справка: массив, список, набор, отображение, кортеж, запись литералов на Java от нашего партнера по JCG Лукаса Эдера из блога JAVA, SQL и AND JOOQ .