28

Java 7に関するさまざまなオンライン記事から、Java7には次のようなコレクションリテラル1があることがわかりました。

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

私の質問は次のとおりです。

  1. of次のように使用できるすべてのコレクションクラスに静的メソッドを提供することはできなかったでしょう。

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

IMOこれは文字通りのバージョンと同じくらい見栄えがよく、また適度に簡潔です。それでは、なぜ彼らは新しい構文を発明しなければならなかったのですか(編集:「新しい」とは「Javaの新しい」を意味します)。

  1. 私が実際にList<String> fruits = [ "Apple", "Mango", "Guava" ];何を得ると言うとき?ListそれはArrayListそれともLinkedList何か他のものでしょうか?

1コメントに記載されているように、コレクションリテラルはJava 7、実際にはJava 8をカットしませんでした(Oracle開発者のBrian Goetzからの電子メールで、この機能を含めない理由を要約しています。これが提案自体です。 。)

4

11 に答える 11

11

質問2への回答:

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

不変のリストを提供します。

サブタイプを指定できないというこの提案の全体的な考え方。コンパイラは、右側のコレクションに応じて適切な実装を選択します。

詳細はこちらをご覧ください:提案:コレクションリテラル

質問1への回答:はい、そうでしょう。それはスタイルの問題です。

于 2010-04-23T18:36:08.590 に答える
7

もう1つの注意点は、リストの場合、これはvar argsを使用すると非常に簡単ですが、マップに対してどのように行うかについて少し考えてみてください。追加のMap.Entryオブジェクトなどを導入しない限り、varargsメソッドに引数のペアを提供する方法はありません。

したがって、既存の構文を使用すると、最終的には

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();
于 2010-04-23T18:05:26.543 に答える
4

上記に言及されていないのは、コレクションのコレクションの単純さです。さまざまな国の通貨名と値を格納する定数が必要だとします。

// 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"] } 
    };

非常に読みやすい12行に膨大な量のデータを詰め込みました。私がArrayList.of(10回)およびいくつかの同様のマップコンストラクター(4回、10個のMap.EntryPair!)を使用した場合、関数呼び出しはコードを肥大化し、読みにくくします。

それは間違いなくシンタックスシュガーの領域にありますが、これは私がJava 7で楽しみにしている一番の機能です(もしそれが出てきたら)。

于 2011-03-31T15:20:52.307 に答える
3

A1はい、可能ですが、どんどん入力する必要があります。

これは確かに本質的に間違っているわけではありませんが、開発者がもっと不満を言うことの1つです。彼ら(そして時々私は自分自身をします)は、Javaが冗長すぎると感じています。

ハードウェアが高速化するにつれて、当初は計算を実行するには高額であった新しいプログラミング言語が実現可能になり、現在ではますます使用され、非常に人気があります。開発者がJavaをもう一度入力しなければならないとき、彼らは、ああ、いやpublic static void main もう一度!すこし。

Java(および一般に静的に型付けされる言語)が実行速度を上げる必要があったことの1つは、実行前(つまり、コンパイル段階)にできるだけ多くの検証を実行することです。

これらの新しいプログラミング言語(特にPythonとRuby)は、同じことを実現するために入力する必要が少ないため、プログラミングを楽しむことができます。

Javaがこれに対して取っている反応は、言語を大きくし、この「シンタックスシュガー」の一部を言語に組み込むことです。それが理由です。

C#のようなプログラミング言語でさえ、開発者コードを少なくするためにこれらの拡張機能(プロパティが頭に浮かぶ)を持っていました。

最後に、これらの追加は言語に役立つと思いますが、互換性を損なうことを避けたり、誰も使用できないほど大きな言語を作成したりするために、慎重に追加する必要があります。

別の方法として、メソッドの名前をより表現しやすくすることもできたと思いますが、Javaの場合は非常に複雑です。おそらく新しい言語で:)。

Map putメソッドのシグネチャは次のようになっている可能性があります:

 /**
  * 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は冗長すぎるため、このソリューションを追加することにしました。

もう1つの拡張機能は数値リテラルであるため、次のように入力できます。

 int million = 1_000_000;

A2:あなたは何か他のものを手に入れるでしょう。

A3 ( kloffyの回答に関する私のコメントを拡張します)。

今日の時点で、Javaで同じコードを書くことができます。

既存のJavaクラスが許可Stage, Scente, Group, Text, ImageView, Imageされている場合は、次のように入力できます。

 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;
                     }};
                 }};
             };
         }};
     }};
 }};
于 2010-04-23T18:41:37.063 に答える
2

それらは、 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
                    }
                }
            ]
        }
    }
}

このスタイルのプログラミングは、確かに特定のアプリケーション分野に適していると思います。結局、それは常に好みの問題です...

于 2010-04-23T18:11:51.377 に答える
1

言語デザインは好みの問題です。そうは言っても、この種のリスト/オブジェクトの初期化は非常に人気があります。たとえば、C#もほぼ同じです。構文は非常に柔軟で、例に示されているように、辞書のようなものをインラインで初期化できます。デザイナーがここで選んだ構文が好きです。

于 2010-04-23T17:57:59.367 に答える
1

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;

これは私たちの生活に本当に新しい何かを追加しますか?うーん、ダメ。それは私たちの生活を少し楽にしますか?私はイエスと思う。

質問の2番目の部分に関しては、実際のタイプが何であるかわかりません。しかし率直に言って、コレクションの実装が何であるかをどのくらいの頻度で気にしますか?特に、そのようなコレクションは比較的小さいと予想されることを考慮に入れてください(すべての値は開発者によって入力されます)。とにかく、あなたが気にするそれらのまれなケースでは、この単純化された構文を使用せず、自分で仕事をしてください。

于 2010-04-23T18:17:49.233 に答える
0

その理由の1つは、ジェネリックオブジェクトのインスタンスを設定しようとすると、チェックof( ... )されていない警告が生成されることだと思います。

その理由は、Java配列に...拡張され、Java配列は汎用インスタンスを好みません。

この特定の問題を扱う仕様の例を次に示します。

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

現在、この簡潔な方法で、チェックされていない警告なしにこの変数を初期化する方法はありません。

于 2010-04-23T18:36:59.270 に答える
0

1つのポイントを明確にするために、彼らは「新しい構文を発明」しませんでした。

元のアイデアがどこから来たのかは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からのものであると言っているわけではありませんが、少なくとも1つの他の言語と一致しているため、より広く使用されている可能性があります。

于 2010-04-23T17:55:20.853 に答える
0

このようなリテラルはPython、Javascript(json)、およびおそらく他の言語に存在するため、これは完全に新しい構文ではありません。

率直に言ってJava7に関する情報はまだ見ていませんが(最近はC ++とJavascriptに焦点が当てられています)、このような言語への追加を見るのは実際には良いことです。

于 2010-04-23T17:59:39.147 に答える
0

そうです、これは単なる空のシンタックスシュガーです。

また、あなたArrayList.of(...)はただの速記になりますnew ArrayList<...>(Arrays.asList(...))

于 2010-04-23T18:22:14.687 に答える