为什么收集文字?

从Java 7上的各种在线文章中我已经知道Java 7将具有如下所示的集合文字1

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

我的问题是:

  1. 难道不可能在所有集合类中提供可以如下使用的静态方法:

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

IMO看起来和文字版本一样好,而且也相当简洁。 那为什么他们必须发明一种新的语法( 编辑: ‘新’我的意思是’新的Java’。)?

  1. 当我说List fruits = [ "Apple", "Mango", "Guava" ]; 我真正得到什么List ? 它是ArrayList还是LinkedList或其他什么?

1正如评论中所指出的,集合文字并没有为Java 7,也不是Java 8做出决定。(这是来自Oracle开发人员Brian Goetz的电子邮件 ,总结了不包括此function的基本原理;这里是提案本身。)

对问题2的回答:

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

给你一个不可变的列表。

这个提议的整个想法是无法指定子类型。 编译器根据右侧的集合选择合适的实现。

阅读详细信息: 提案:收集文字

回答问题1:是的,它会有。 这是一种风格问题。

另外需要注意的是,对于列表来说,使用var args非常容易,但是想一想你是如何为地图做的。 除非您引入额外的Map.Entry对象或类似的东西,否则无法为var args方法提供参数对。

因此,使用现有的语法,你最终会得到

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

哪会很快累。

即使你走下了使用构建器模式的道路(就像我们一样),那也很难看

 Map map = CollectionUtil.map() .put( "key1", "value1" ) .put( "key2", "value2" ) .map(); 

上面没有提到的是集合集合的简单性。 假设您希望常量来存储不同国家/地区的货币名称和值。

 // Currency devisions by country, and their various names Map>> 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 (十次)和一些类似的地图构造函数(四次,有十个Map.EntryPair!),函数调用会使代码膨胀并使其更难阅读。

虽然它肯定属于语法糖的领域,但这是我在Java 7中期待的第一个function(如果它已经发布)。

A1是的可能,但要求您输入越来越多。

虽然这当然不是什么错误,但这是开发人员抱怨的事情之一。 他们(有时我自己做)觉得Java 太冗长了 。

随着硬件变得越来越快,新的编程语言在开始时太昂贵而无法执行计算变得可行,并且它们现在被越来越多地使用并且非常受欢迎。 当开发人员不得不再次输入Java时,他们会感觉到,就像哦不行:public static void main 的种类。

Java(以及通常静态类型语言)必须提高执行速度的一件事是运行之前执行尽可能多的validation(即,在编译阶段)

这些新的编程语言(非常精通Python和Ruby)让编程变得愉快,因为你必须输入更少的内容来实现相同的function。

Java正在采取的反应是,使语言更大,并将一些“语法糖”纳入语言,这就是原因。

即使像C#这样的编程语言也有这些扩展function(我想到的属性),以减少开发人员代码。

最后,我认为这些附加内容有益于语言,但必须非常小心地添加它们,以避免破坏兼容性和/或创建一个如此之大的语言,以至于没有人可以使用它。

我认为另一种选择是允许这些方法在其名称中更具表现力,但对于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"); 

是……呃嗯太冗长了,他们决定添加这个解决方案。

另一个增强function是数字文字,因此您可以输入:

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

他们可能受到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 } } ] } } } 

我认为这种编程方式肯定适用于某些应用领域。 最后,它始终是品味的问题……

语言设计是品味的问题。 话虽如此,这种列表/对象初始化已经变得非常流行。 例如,C#几乎完全相同。 语法非常灵活,正如您的示例所示,可以让您初始化内联字典。 我更喜欢设计师在这里选择的语法。

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; 

这是否为我们的生活增添了一些新东西? 好吧,不。 它会让我们的生活更轻松吗? 我想是的。

关于问题的第二部分,我不知道实际的类型是什么。 但坦率地说,你经常关心什么是集合实现? 特别是考虑到这些集合预计相对较小(所有值都由开发人员键入)。 无论如何,在您关心的极少数情况下,请不要使用这种简化的语法并自己完成工作。

它不是全新的语法,因为Python,Javascript(json)以及其他语言中都存在这样的文字。

我还没有看到有关java 7的任何信息尚未坦白(最近专注于C ++和Javascript),但实际上很高兴看到这种语言的增加。

只是澄清一点 – 他们没有“发明新语法”。

我不是100%确定原始想法的来源,而是使用“[]”来表示列表,并使用“{}”来表示Perl中存在的地图(其中那些用于构建数组引用和散列引用)。

严格来说perl中没有“set”,但是set的最惯用的实现是map(map set member to 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,但它与至少一种其他语言一致,因此可能有更广泛的用途。

你是对的,这只是空的句法糖。

你的ArrayList.of(...)也只是new ArrayList<...>(Arrays.asList(...))

我认为其中一个原因是of( ... )会产生一个未经检查的警告,如果你试图用通用对象的实例填充它。

原因是, ...扩展为java数组,而java数组不喜欢generics实例。

以下是处理此特定问题的规范示例:

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

目前没有办法以这种简洁的方式初始化此变量,也没有未经检查的警告。