Почему литералы набора?

От различных статей онлайн о Java 7 я узнал тот Java 7, будет иметь набор literals1 как следующее:

List fruits = [ "Apple", "Mango", "Guava" ];
Set flowers = { "Rose", "Daisy", "Chrysanthemum" };
Map hindiNums = { 1 : "Ek", 2 : "Do", 3 : "Teen" }; 

Мои вопросы:

  1. Не был бы он быть возможным обеспечить статический метод of во всех классах набора, которые могли использоваться следующим образом:

List fruits = ArrayList.of("Apple", "Mango", "Guava");

IMO это выглядит столь же хорошим как литеральная версия и также довольно кратко. Почему затем сделал они должны изобрести новый синтаксис (РЕДАКТИРОВАНИЕ: 'новым' я имею в виду 'в новинку для Java'.)?

  1. Когда я говорю List fruits = [ "Apple", "Mango", "Guava" ]; что List я на самом деле добрался бы? Это было бы ArrayList или LinkedList или что-то еще?

1, Как отмечено в комментариях, литералы набора не сделали сокращение для Java 7, ни действительно Java 8. (Вот электронное письмо от Brian Goetz, разработчика Oracle, суммируя объяснение для не включая эту функцию; и вот само предложение.)

27
задан Willi Mentzel 12 October 2017 в 13:30
поделиться

10 ответов

Ответ на вопрос 2:

final List<Integer> piDigits = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9];

дает вам неизменяемый список.

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

Подробности читайте здесь: Предложение: Литералы коллекции

Ответ на вопрос 1: да, было бы. Это вопрос стиля.

11
ответ дан 28 November 2019 в 05:43
поделиться

Языковое оформление - дело вкуса. При этом такой вид инициализации списка / объекта стал очень популярным. Например, в C # есть почти то же самое. Синтаксис довольно гибкий и, как показывают даже ваши примеры, позволяет вам инициализировать что-то вроде встроенного словаря. Мне больше нравится синтаксис, который здесь выбрали дизайнеры.

1
ответ дан 28 November 2019 в 05:43
поделиться

ИМО, это просто синтаксический сахар , который немного упрощает код. Почему вас не удивляет такой же сахар:

int []arr1 = new int[] {1,2,3};
int []arr2 = {1,2,3};

Это просто удобный способ выразить простую идею вместо того, чтобы писать что-то вроде

int []arr = new int[3];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;

Добавляет ли это что-то действительно новое в нашу жизнь? Ну нет. Облегчает ли это нашу жизнь? Я думаю да.

Что касается второй части вопроса, я не знаю, какими будут настоящие типы. Но, честно говоря, как часто вас волнует реализация коллекции? Особенно с учетом того, что такие коллекции должны быть относительно небольшими (все значения вводятся разработчиком). В любом случае, в тех редких случаях, когда вам все равно, просто не используйте этот упрощенный синтаксис и выполняйте работу самостоятельно.

1
ответ дан 28 November 2019 в 05:43
поделиться

Возможно, они были вдохновлены декларативным стилем программирования JavaFX . Однако, если это так, я разочарован тем, что они также не полностью поддержали объектные литералы. Вот пример объектных литералов в JavaFX:

Stage {
    title: "Group-Nodes-Transformation"
    scene: Scene {
        width: 600
        height: 600
        content: Group {
            content: [
                Circle {
                    centerX: 300
                    centerY: 300
                    radius: 250
                    fill: Color.WHITE
                    stroke: Color.BLACK
                },
                Text {
                    x: 300
                    y: 300
                    content: "Mr. Duke"
                },
                ImageView {
                    image: Image {
                        url: "D:\\TEST\\Documents\\duke.png"
                        width:50
                        height:50
                    }
                }
            ]
        }
    }
}

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

2
ответ дан 28 November 2019 в 05:43
поделиться

A1 Да, возможно, но требует, чтобы вы вводили все больше и больше.

Хотя в этом нет ничего плохого, разработчики больше жалуются на это. Они (а иногда и я сам) считают, что Java слишком многословен .

По мере того, как оборудование становилось все быстрее, новые языки программирования, которые вначале были слишком дорогими для выполнения вычислений, стали возможными, и теперь они используются все больше и больше и очень популярны. Когда разработчикам снова приходится вводить Java, они снова чувствуют себя как о нет: , public static void main ! вид.

Одна из вещей, которые Java (и языки статического типа в целом) должны были увеличить скорость выполнения, - это выполнить как можно больше проверок перед запуском (то есть на этапе компиляции)

Эти новые языки программирования (особенно Python и Ruby) доставляют удовольствие при программировании, потому что вам нужно меньше печатать, чтобы добиться того же.

Реакция Java на это заключается в том, чтобы сделать язык больше и включить в него часть этого «синтаксического сахара», вот почему.

Даже языки программирования, такие как C #, имели эти расширенные функции (на мой взгляд, свойства), чтобы уменьшить объем кода разработчика.

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

Я думаю, что альтернативой было бы позволить методам быть более выразительными в своих именах, но это очень сложно для Java. Возможно на новом языке :).

Сигнатура метода размещения карты могла быть такой:

 /**
  * Analog to put( Object k, Object v );
  */
 public [( Object = k )]=( Object  v ) {
 } 

Это позволяет использовать имя метода: [(ключ)] = (значение) и в конечном итоге опускать круглые скобки (как в Ruby или изначально в Smalltalk), поэтому этот метод будет выглядеть так:

 Map map = ....
 map.["name"]="Oscar";

Поскольку это невозможно (потому что [] = не являются допустимыми идентификаторами метода), и запись:

 map.put("name","Oscar");

Is ... mmhh слишком многословен, они решили добавить это решение.

Еще одним усовершенствованием являются числовые литералы, поэтому вы можете ввести:

 int million = 1_000_000;

A2 : вы получите что-то еще.

A3 (расширяя мой комментарий к ответу kloffy ).

Вы могли бы написать тот же самый код на Java, что и сегодня.

Допустим, Stage, Scente, Group, Text, ImageView, Image были существующими классами Java, вы можете ввести:

 new Stage() {{
     title  =  "Group-Nodes-Transformation";
     scene  =  new Scene() {{
         width =  600;
         height = 600;
         content = new Group() {{
             content = new Object[] =  {
                 new Circle() {{
                     centerX = 300;
                     centerY = 300;
                     radius = 250;
                     fill = Color.WHITE;
                     stroke = Color.BLACK;
                 }},
                 new Text() {{
                     x = 300;
                     y = 300;
                     content = "Mr. Duke";
                 }},
                 new ImageView() {{
                     image = new  Image() {{
                         url = "D:\\TEST\\Documents\\duke.png"
                         width = 50;
                         height = 50;
                     }};
                 }};
             };
         }};
     }};
 }};
3
ответ дан 28 November 2019 в 05:43
поделиться

Просто чтобы прояснить один момент - они этого не сделали " изобретать новый синтаксис ».

Я не уверен на 100%, откуда взялась первоначальная идея, но использование "[]" для обозначения списков и "{}" для обозначения карт существует в Perl (где они используются при построении ссылок на массивы и хеш-ссылок) .

Строго говоря, в perl нет «набора», но наиболее идиоматическая реализация набора - это карта (член набора карт равен 1), поэтому «{}» также подходит.

Итак, Perl сказал бы точно то же самое, что вы перечислили:

$fruits = [ "Apple", "Mango", "Guava" ]; # Creates array reference
$flowers = { "Rose" => 1, "Daisy" => 1, "Chrysanthemum" => 1 };
     # or { map {$_=>1} ("Rose", "Daisy", "Chrysanthemum"))
$hindiNums = { 1 => "Ek", 2 => "Do", 3 => "Teen" }; 

Я, конечно, не говорю, что вышеперечисленное пришло из Perl, но оно согласуется по крайней мере с одним другим языком и, следовательно, возможно, с более широким использованием .

0
ответ дан 28 November 2019 в 05:43
поделиться

Также следует отметить, что для списков это очень просто с помощью var args, но немного подумайте как бы вы это сделали для карты. Невозможно передать пары аргументов методу var args, если вы не введете дополнительный объект Map.Entry или что-то в этом роде.

Таким образом, используя существующий синтаксис, вы получите

Map<String,String> map = HashMap.of( new Entry( "key1", "value1" ), 
                                     new Entry( "key2", "value2" ) );

, что очень быстро утомит вас.

Даже если вы пойдете по пути использования шаблона компоновщика (как это делаем мы), то это будет довольно некрасиво

Map<String,String> map = CollectionUtil.<String,String>map()
                                        .put( "key1", "value1" )
                                        .put( "key2", "value2" )
                                        .map();
7
ответ дан 28 November 2019 в 05:43
поделиться

Это не совсем новый синтаксис, поскольку такие литералы присутствуют в Python, Javascript (json) и, возможно, в других языках.

Я еще не видел никакой информации о java 7, если честно (в последнее время я сосредоточился на C ++ и Javascript), но на самом деле приятно видеть такое дополнение к языку.

0
ответ дан 28 November 2019 в 05:43
поделиться

Вы правы, это просто синтаксический сахар.

Также ваш ArrayList.of (...) будет просто короткой рукой для нового ArrayList <...> (Arrays.asList (...))

0
ответ дан 28 November 2019 в 05:43
поделиться

Я думаю, одна из причин заключается в том, что из (...) генерирует предупреждение unchecked если вы попытаетесь заполнить его экземплярами общих объектов.

Причина, ... расширяется до массива Java, а массивы Java не любят общие экземпляры.

Вот пример из спецификации, который касается этой конкретной проблемы:

List<List<Integer>> pascalsTriangle =
    [[1],
     [1, 1],
     [1, 2, 1],
     [1, 3, 3, 1],
     [1, 4, 6, 4, 1]]

В настоящее время нет возможности инициализировать эту переменную таким кратким образом и без предупреждения снятого флажка .

0
ответ дан 28 November 2019 в 05:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: