从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看起来和文字版一样好,而且也相当简洁。那为什么他们必须发明一种新的语法(编辑:按'新'我的意思是'刚接触Java'。)?
答案 0 :(得分:11)
回答问题2:
final List<Integer> piDigits = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9];
为您提供不可变列表。
此提案的整个想法是无法指定子类型 。编译器根据右侧的集合选择合适的实现。
请在此处阅读详细信息:Proposal: Collection Literals
回答问题1:是的,它会有。这是一种风格问题。
答案 1 :(得分:7)
另外需要注意的是,对于列表来说,使用var args非常容易,但是想一想你是如何为地图做的。除非你引入一个额外的Map.Entry对象或类似的东西,否则无法为var args方法提供参数对。
因此,使用现有语法,您最终会使用
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();
答案 2 :(得分: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
(十次)和一些类似的地图构造函数(四次,有十个Map.EntryPair!),函数调用会使代码膨胀并使其更难以阅读。
虽然它肯定属于语法糖的领域,但这是我在Java 7中期待的第一个功能(如果它已经发布)。
答案 3 :(得分:3)
A1 是的,但是要求您输入越来越多的内容。
虽然这肯定不是什么错误,但这是开发人员抱怨的事情之一。他们(有时我自己做)会觉得Java is too verbose。
随着硬件变得越来越快,新的编程语言在开始时太昂贵而无法执行计算变得可行,并且它们现在被越来越多地使用并且非常受欢迎。当开发人员必须再次输入Java时,他们会感觉到,比如哦不是:,再次public static void main
!。
Java(以及通常静态类型语言)必须提高执行速度的一件事是在运行之前(即在编译阶段)执行尽可能多的验证
这些新的编程语言(非常精通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");
是......呃嗯啰嗦,他们决定添加这个解决方案。
另一个增强功能是数字文字,因此您可以输入:
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;
}};
}};
};
}};
}};
}};
答案 4 :(得分: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
}
}
]
}
}
}
我认为这种编程方式肯定适用于某些应用领域。最后,这总是一个品味问题......
答案 5 :(得分:1)
语言设计是一种品味问题。话虽如此,这种列表/对象初始化已经变得非常流行。例如,C#几乎完全相同。语法非常灵活,正如您的示例所示,可以让您初始化类似内联字典的内容。我更喜欢设计师在这里选择的语法。
答案 6 :(得分:1)
IMO这只是一个Syntactic sugar,可以简化代码。为什么你不会对同类糖感到惊讶:
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;
这是否为我们的生活增添了一些新东西?好吧,不。它会让我们的生活更轻松吗?我想,是的。
关于问题的第二部分,我不知道实际的类型是什么。但坦率地说,你经常关心什么是集合实现?特别是考虑到这些集合预计相对较小(所有值都由开发人员键入)。无论如何,在您关心的极少数情况下,请不要使用这种简化的语法并自己完成工作。
答案 7 :(得分:0)
只是澄清一点 - 他们没有“发明新语法”。
我不是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,当然,它与至少一种其他语言一致,因此可能有更广泛的用途。
答案 8 :(得分:0)
这并不是全新的语法,因为Python,Javascript(json)和其他语言中都存在这样的文字。
我还没有看到有关Java 7的任何信息尚未坦白(最近专注于C ++和Javascript),但实际上很高兴看到这种语言的添加。
答案 9 :(得分:0)
你是对的,这只是空的句法糖。
此外,ArrayList.of(...)
只是new ArrayList<...>(Arrays.asList(...))
答案 10 :(得分:0)
我认为其中一个原因是of( ... )
会生成未经检查的警告,如果您尝试使用通用对象的实例填充它。
原因是...
扩展为java数组,而java数组不喜欢泛型实例。
以下是处理此特定问题的规范中的示例:
List<List<Integer>> pascalsTriangle =
[[1],
[1, 1],
[1, 2, 1],
[1, 3, 3, 1],
[1, 4, 6, 4, 1]]
目前无法以这种简洁的方式初始化此变量,并且没有未选中警告。