Skip to content

Commit d7c95f3

Browse files
committed
Merge pull request giantray#18 from yunshuipiao/master
在java中声明数组
2 parents db28520 + 5bb65f7 commit d7c95f3

File tree

4 files changed

+146
-56
lines changed

4 files changed

+146
-56
lines changed

contents/Declare-array-in-Java.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
##在java中声明数组
2+
3+
###问题描述:
4+
你是如何在jva中声明数组的。
5+
6+
你可以进行用数组声明或者数组常量(注意:当你声明或者立即影响了变量,数组常量将不能再用来分配一个数组)
7+
对于原始类型:
8+
```
9+
int[] myIntArray = new int[3];
10+
int[] myIntArray = {1, 2, 3};
11+
int[] myIntArray = new int[]{1, 2, 3};
12+
```
13+
杜宇类,比如String类,也是相同的:
14+
```
15+
String[] myStringArray = new String[3];
16+
String[] myStringArray = {"a", "b","c"};
17+
String[] myStringArray = new String[]("a", "b", "c");
18+
```
19+
[stack overflow链接:Declare array in Java?](http://stackoverflow.com/questions/1200621/declare-array-in-java#)
20+
21+
22+
23+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# What is reflection, and why is it useful?
2+
3+
##问题描述
4+
反射是什么,为什么它是有用的?
5+
我特别感兴趣的是java,但我认为任何语言的原理都是相同的。
6+
7+
##回答
8+
反射是被用来描述代码的,可以检查同一系统(或者自身)的其他代码。
9+
10+
举个例子,在java中你有一个不知道具体类型的对象,并且你可能会调用它的dosomething的方法(如果存在的话)java的静态类型系统并没有设计来支持此用法,除非对象符合已知的接口。但是用反射,你的代码能查看对象,并找出一个dosomething的方法(如果有的话),然后你可以调用他。
11+
因此,一个例子如下(想象在问题中的对象foo):
12+
```
13+
Method method = foo.getClass().getMethod("dosomething",null);
14+
method.invoke(foo,null); //调用foo的dosomething方法
15+
```
16+
java中一个非常常见的用例是使用注释。JUnit 4,举个例子,将使用反射来浏览你的标记有@test注释的类方法,之后当运行测试单元时进行调用。
17+
18+
[有很多好的反射例子,可以用来入门](http://docs.oracle.com/javase/tutorial/reflect/index.html)
19+
20+
最后,其概念在其他支持反射的静态类型语言中是非常相似的。在动态语言中,上面描述的用例并不是必要的(因为编译器允许任何方法都能被任何对象调用,在运行时如果不存在就会失败),但是第二种情况,寻找能以某种确定的方式工作的方法任然是常见的。
21+
22+
[原文链接:What is reflection, and why is it useful?](http://stackoverflow.com/questions/37628/what-is-reflection-and-why-is-it-useful)
23+
24+
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Why can't I switch on a String
2+
3+
##问题描述
4+
为什么不能用string类型进行switch判断?
5+
是否作为一个功能将会被添加如java后续版本中?
6+
有人能给我一篇文章,或者解释一下为什么不能这样做,说明java中switch语句的运行方式?
7+
8+
##回答
9+
用string作为case来使用switch语句已经在java SE7中被实现了,距离这个问题被提出至少有16年了。一个明确的原因迟迟未提供,但是性能要求它必须这样做。
10+
11+
**Implementtation in JDK 7**
12+
这个特性现在已经被实现,`javac`with a ["de-sugaring peocess"](http://blogs.oracle.com/darcy/entry/project_coin_string_switch_anatomy)。一个高级的,清楚的使用String常量的语法能在case声明中被使用,会在编译时扩展成为更复杂的代码模式,生成的代码使用jvm指令也一直存在。
13+
switch将string用作case在编译时翻译成两个switch。第一次每一个string映射到一个独一无二的整数,它的位置在原始的switch上。这是通过在case上的hashcode进行switch选择,相应的案例是一个if语句,测试字符串是否相等。如果有哈希碰撞,测试就像`if-else-if`
14+
第二次switch反映在最初的源代码中,用相应位置上的整数代替响应的string标签case。这两步过程更容易保留原始switch的流程控制。
15+
16+
**Switchs in the JVM**
17+
在switch的更多深层技术上,可以参考JVM规范,[compliation of switch statements](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-3.html#jvms-3.10)有响应的描述。简单概括说,根据使用的常量的多少,switch有两种不同的JVM指令来执行,每种情况下都取决于使用整数常量来有效的执行。
18+
19+
如果常量很多,case会在一个指令表被用作索引(减去最小值后)——`tablewitch`指令
20+
如果常量相对较少,那么可用二分查找来找到正确的case--`lookupswitch`指令
21+
22+
`de-sugaring`中,一个switch(String)的对象,两种指令都会被用到。`lookupswitch`指令适用于第一次计算哈希值找到初始位置,由此产生的顺序表很自然的用`tableswitch`指令
23+
24+
两种指令在编译时都需要将整数常量赋值给每个case。在运行时,虽然`tableswitch`O(1)的性能通常要好于`lookupswitch`O(log(n))的性能,但是前者需要一定的分析来决定是否有足够的case来满足时间空间的平衡。Bill Venners的文章[a great article](http://www.artima.com/underthehood/flowP.html)在细节上讲述的更多,以及涉及到从底层的出发,来看其他java流程控制指令。
25+
26+
**Before JDK 7**
27+
在JDK之前,枚举近似的用String作为switch的case,这使用了静态方法`valueOf`,编译器生成了一个枚举类型。例子如下:
28+
```
29+
Pill p = Pill.valueOf(str);
30+
switch(p) {
31+
case RED:pop();break;
32+
case BLUE:push();break;
33+
}
34+
```
35+
36+
[阅读原文:Why can`t I switch on a String](http://stackoverflow.com/questions/338206/why-cant-i-switch-on-a-string)
37+
38+
39+
40+
41+
Lines changed: 58 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,58 @@
1-
##如何通过一行代码初始化ArrayList
2-
3-
###问题
4-
为了测试,我需要临时快速创建一个list。一开始我这样做:
5-
```java
6-
ArrayList<String> places = new ArrayList<String>();
7-
places.add("Buenos Aires");
8-
places.add("Córdoba");
9-
places.add("La Plata");
10-
```
11-
之后我重构了下
12-
```java
13-
ArrayList<String> places = new ArrayList<String>(
14-
Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));
15-
```
16-
是否有更加简便的方法呢?
17-
18-
###回答
19-
20-
####常见方式
21-
实际上,也许“最好”的方式,就是你写的这个方式,因为它不用再创建新的`List`:
22-
```
23-
ArrayList<String> list = new ArrayList<String>();
24-
list.add("A");
25-
list.add("B");
26-
list.add("C");
27-
```
28-
只是这个方式看上去要多写些代码,让人郁闷
29-
30-
####匿名内部类
31-
当然,还有其他方式,例如,写一个匿名内部类,然后在其中做初始化(也被称为 brace initialization):
32-
```
33-
ArrayList<String> list = new ArrayList<String>() {{
34-
add("A");
35-
add("B");
36-
add("C");
37-
}};
38-
```
39-
但是,我不喜欢这个方式。只是为了做个初始化,却要在`ArrayList`的同一行后面加这么一坨代码。
40-
41-
####Arrays.asList
42-
```
43-
List<String> places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata");
44-
```
45-
####Collections.singletonList
46-
```
47-
List<String> places = Collections.singletonList("Buenos Aires");
48-
```
49-
注意:后面的这两种方式,得到的是一个定长的`List`(如果add操作会抛异常)。如果你需要一个不定长的`List`,可以这样做:
50-
```
51-
ArrayList<String> places = new ArrayList<>(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));
52-
53-
```
54-
55-
stackoverflow链接:
56-
http://stackoverflow.com/questions/1005073/initialization-of-an-arraylist-in-one-line
1+
如何用一句代码初始化一个ArrayList
2+
##问题描述
3+
4+
我想创建一个用于测试的的选项列表,首先:
5+
```
6+
ArrayList<String> places = new ArrayList<String>();
7+
places.add("Buenos Aires");
8+
places.add("Córdoba");
9+
places.add("La Plata");
10+
```
11+
之后我如下重构了代码:
12+
```
13+
ArrayList<String> places = new ArrayList<String>(
14+
Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));
15+
```
16+
是否还有更好的方法来完成这个功能呢?
17+
18+
###回答一(750赞)
19+
实际上,可能初始化ArrayList的“最好”的方法就如你所写的一样,无论如何,都不需要创建一个新的list。
20+
```
21+
ArrayList<String> list = new ArrayList<String>();
22+
list.add("A");
23+
list.add("B");
24+
list.add("C");
25+
```
26+
但问题是,有相当多多的类型需要参考`list`实例。
27+
可以有替代的办法,比如使用匿名内部类,初始化实例,也被称为一个“double brace initailzation"。
28+
```
29+
ArrayList<String> list = new ArrayList<String>() {{
30+
add("A");
31+
add("B");
32+
add("C");
33+
}};
34+
```
35+
然而,我不是太喜欢这种方法,因为这样得到是一个初始化一个实例的ArrayList的子类,并且这个类只是被用来创建一个对象,好像我有点过分了。
36+
如果 `the Collection Literals proposal for Project Coin (抱歉,不知怎么翻译)`被接受的话,可能是最好的方式(将被引入Java7,但它不太可能成为Java 8的一部分)。
37+
[更多关于the Collection Literals proposal的内容链接](http://stackoverflow.com/questions/924285/efficiency-of-java-double-brace-initialization)
38+
```
39+
List<String> list = ["A","B","C"];
40+
```
41+
不行的是,并没有帮到你。这会初始化成一个不可变的列表,而不是一个ArrayList,而且,现在还不能用。
42+
43+
###回答二(714赞)
44+
如果你只是作为一个List声明的话,这样可能会更简单.(必须是ArrayList吗)
45+
```
46+
List<String> places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata");
47+
```
48+
或者只有一个元素:
49+
```
50+
List<String> places = Collections.singletonList("Buenos Aires");
51+
```
52+
这意味着places是不可变的(如果改变它,将会抛出一个异常).
53+
让一个可变列表是一个具体的ArrayList,您可以从不可变列表创建一个ArrayList:
54+
```
55+
ArrayList<String> places = new ArrayList<>(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));
56+
```
57+
[原文链接:Initialization of an ArrayList in one line](http://stackoverflow.com/questions/1005073/initialization-of-an-arraylist-in-one-line)
58+

0 commit comments

Comments
 (0)