Подтвердить что ты не робот

Почему сборники?

Из различных онлайн-статей на Java 7 я узнал, что Java 7 будет иметь литералы коллекции 1 как показано ниже:

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

Мои вопросы:

  • Было бы невозможно предоставить статический метод of во всех классах коллекции, которые можно было бы использовать следующим образом:

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

IMO выглядит так же хорошо, как буквальная версия, а также достаточно кратким. Почему тогда им пришлось придумать новый синтаксис ( EDIT: По "новому" я имею в виду "новый для Java".)?

  1. Когда я скажу List<String> fruits = [ "Apple", "Mango", "Guava" ];, что List мог бы я получить? Это будет ArrayList или LinkedList или что-то еще?

1 Как отмечалось в комментариях, литералы коллекции не вырезали для Java 7 и не Java 8. (Здесь электронная почта от Брайана Гетца, разработчика Oracle, в котором излагается обоснование отсутствия этой функции, а вот .)

4b9b3361

Ответ 1

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

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

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

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

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

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

Ответ 2

Еще одно замечание: для списков это очень просто, используя 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();

Ответ 3

Не упоминается выше простота коллекций коллекций. Допустим, вы хотите, чтобы константа хранила имена и значения валют разных стран.

// Currency devisions by country, and their various names
Map<String,Map<Float,List<String>>> CURRENCIES =
    { "US" : { 1 : ["dollar","buck"],
               0.25 : ["quarter"],
               0.10 : ["dime"],
               0.05 : ["nickel"],
               0.01 : ["penny"] },
      "UK" : { 1 : ["pound"],
               1.05 ["guinea"],
               0.125 : ["half crown"],
               0.05 : ["shilling","bob"],
               0.025 : ["sixpence"] } 
    };

У меня есть огромное количество данных в двенадцати чрезвычайно разборчивых строках. Если бы я использовал ArrayList.of (десять раз) и некоторый похожий конструктор карты (четыре раза, с десятью Map.EntryPair!), Вызовы функций раздули бы код и сделали его значительно труднее для чтения.

Хотя он определенно находится в области синтаксического сахара, это функция №1, с которой я с нетерпением жду в Java 7 (если она когда-либо выйдет).

Ответ 4

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

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

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

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

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

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

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

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

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

Подпись метода "Положить карту" могла бы быть такой:

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

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

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

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

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

Я... 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;
                     }};
                 }};
             };
         }};
     }};
 }};

Ответ 5

Возможно, они были вдохновлены стилем декларативного программирования 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
                    }
                }
            ]
        }
    }
}

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

Ответ 6

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

Ответ 7

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

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;

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

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

Ответ 8

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

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

Там нет "набора" в 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, конечно, но это согласуется с хотя бы одним другим языком и, возможно, с более широким использованием.

Ответ 9

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

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

Ответ 10

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

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

Ответ 11

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

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

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

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

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