Skip to content

Commit 34adab9

Browse files
committed
fix format
1 parent 5020f02 commit 34adab9

10 files changed

+52
-20
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ stackoverflow-Java-top-qa
1616
* [public,protected,private,不加修饰符。有什么区别呢?](https://github.com/giantray/stackoverflow-java-top-qa/blob/master/contents/in-java-whats-the-difference-between-public-default-protected-and-private.md)
1717
* [如何判断数组Array是否包含指定的值?](https://github.com/giantray/stackoverflow-java-top-qa/blob/master/contents/in-java-whats-the-difference-between-public-default-protected-and-private.md)
1818
* [重写(Override)equlas和hashCode方法时应考虑的问题](https://github.com/giantray/stackoverflow-java-top-qa/blob/master/contents/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java.md)
19-
* [从一个多层嵌套循环中直接退出](https://github.com/giantray/stackoverflow-java-top-qa/blob/master/contents/breaking-out-of-nested-loops-in-java.md)
19+
* [从一个多层嵌套循环中直接跳出](https://github.com/giantray/stackoverflow-java-top-qa/blob/master/contents/breaking-out-of-nested-loops-in-java.md)
2020

2121

2222
> 编程技巧

contents/avoiding-null-statements-in-java.md

+13-5
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,27 @@ if (someobject != null) {
1212
###回答
1313

1414
这是初、中级程序猿经常会遇到的问题。他们总喜欢在方法中返回null,因此,在调用这些方法时,也不得不去判空。另外,也许受此习惯影响,他们总潜意识地认为,所有的返回都是不可信任的,为了保护自己程序,就加了大量的判空。
15-
吐槽完毕,回到这个题目本身:
16-
进行判空前,请区分以下两种情况:
15+
16+
吐槽完毕,回到这个题目本身,进行判空前,请区分以下两种情况:
17+
1718
1. null 是一个有效有意义的返回值(Where null is a valid response in terms of the contract; and)
1819
2. null是无效有误的(Where it isn't a valid response.)
1920

2021
你可能还不明白这两句话的意思,不急,继续往下看,接下来将详细讨论这两种情况
2122

2223
####先说第2种情况
2324
null就是一个不合理的参数,就应该明确地中断程序,往外抛错误。这种情况常见于api方法。例如你开发了一个接口,id是一个必选的参数,如果调用方没传这个参数给你,当然不行。你要感知到这个情况,告诉调用方“嘿,哥们,你传个null给我做甚"。
25+
2426
相对于判空语句,更好的检查方式有两个
25-
(1)assert语句,你可以把错误原因放到assert的参数中,这样不仅能保护你的程序不往下走,而且还能把错误原因返回给调用方,岂不是一举两得。(原文介绍了assert的使用,这里省略)
26-
(2)也可以直接抛出空指针异常。上面说了,此时null是个不合理的参数,有问题就是有问题,就应该大大方方往外抛。
27+
28+
1. assert语句,你可以把错误原因放到assert的参数中,这样不仅能保护你的程序不往下走,而且还能把错误原因返回给调用方,岂不是一举两得。(原文介绍了assert的使用,这里省略)
29+
2. 也可以直接抛出空指针异常。上面说了,此时null是个不合理的参数,有问题就是有问题,就应该大大方方往外抛。
2730

2831
####第1种情况会更复杂一些。
2932
这种情况下,null是个”看上去“合理的值,例如,我查询数据库,某个查询条件下,就是没有对应值,此时null算是表达了“空”的概念。
33+
3034
这里给一些实践建议:
35+
3136
- 假如方法的返回类型是collections,当返回结果是空时,你可以返回一个空的collections(empty list),而不要返回null.这样调用侧就能大胆地处理这个返回,例如调用侧拿到返回后,可以直接print list.size(),又无需担心空指针问题。(什么?想调用这个方法时,不记得之前实现该方法有没按照这个原则?所以说,代码习惯很重要!如果你养成习惯,都是这样写代码(返回空collections而不返回null),你调用自己写的方法时,就能大胆地忽略判空)
3237
- 返回类型不是collections,又怎么办呢?
3338
那就返回一个空对象(而非null对象),下面举个“栗子”,假设有如下代码
@@ -44,6 +49,7 @@ public interface Parser {
4449
解决这个问题的一个方式,就是使用Null Object pattern(空对象模式)
4550

4651
我们来改造一下
52+
4753
类定义如下,这样定义findAction方法后,确保无论用户输入什么,都不会返回null对象
4854
public class MyParser implements Parser {
4955
private static Action DO_NOTHING = new Action() {
@@ -59,7 +65,7 @@ public class MyParser implements Parser {
5965

6066

6167
对比下面两份调用实例
62-
1. 冗余:每获取一个对象,就判一次空
68+
1. 冗余: 每获取一个对象,就判一次空
6369
```java
6470
Parser parser = ParserFactory.getParser();
6571
if (parser == null) {
@@ -73,7 +79,9 @@ if (action == null) {
7379
```
7480

7581
2. 精简
82+
```java
7683
ParserFactory.getParser().findAction(someInput).doSomething();
84+
```
7785
因为无论什么情况,都不会返回空对象,因此通过findAction拿到action后,可以放心地调用action的方法。
7886

7987

contents/breaking-out-of-nested-loops-in-java.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
##从一个多层嵌套循环中直接退出
1+
##从一个多层嵌套循环中直接跳出
22

33
###问题
44
Java中如何从一个多层嵌套循环中退出,例如下面,有两个循环,break只能退出一个for循环,不能直接跳过第二个for循环

contents/create-arraylist-arraylistt-from-array-t.md

+2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ Arrays.asList(array)或者Arrays.asList(new Element(1),new Element(2),new Elemen
1616
2. 如果修改数组的值,list中的对应值也会改变!
1717

1818
如果希望避免这两个坑,请改用这个方式
19+
```java
1920
Collections.addAll(arraylist, array);
21+
```
2022

2123
stackoverflow原址:
2224
http://stackoverflow.com/questions/157944/how-to-create-arraylist-arraylistt-from-array-t

contents/is-java-pass-by-reference-or-pass-by-value.md

+9-5
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,27 @@
33
###概念定义
44
在开始之前,我们先理解按值传递、按引用传递的概念。
55
1. 什么是值传递?
6-
指的是在方法调用时,传递的参数是按值的拷贝传递。按值传递重要特点:传递的是值的拷贝,也就是说传递后就互不相关了,每个值都对应到一个地址空间
6+
指的是在方法调用时,传递的参数是按值的拷贝传递。按值传递重要特点:传递的是值的拷贝,也就是说传递后就互不相关了,**每个值都对应到一个地址空间**
77
2. 什么是引用传递
8-
指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)
8+
指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。**传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)**
99

1010
###结论
1111
明确地说,java都是按值传递的!java的世界里,都是按值传递。其实按值、按引用都只是个概念,关键是我们如何去理解java传参的本质。
1212

1313
###例子
1414
下面就结合一个例子来说
15+
1516
有些情况下,所参数参数的值,是个“引用",这一点容易让人产生困惑。
1617

1718
请看下面的例子
19+
1820
首先有如下代码
19-
[java] view plaincopyprint?
21+
```java
2022
Dog myDog = new Dog("Rover");
21-
foo(myDog);
23+
foo(myDog);
24+
```
2225
这时,你传给了foo函数一个参数,这个参数值,是个引用,也就是Rover这只dog的内存地址(这只是粗略的说明,因为在java中,这个地址并非是真正的地址)
26+
2327
假设这时候Rover的地址是42,那么,我们就是传了42这个地址给foo方法
2428
```java
2529
public void foo(Dog someDog) {
@@ -41,6 +45,7 @@ someDog,也就是函数外声明的myDog,name从Rover被改成了Max
4145

4246
###重要提醒
4347
**再总结下Java初学者容易犯错的地方:**
48+
4449
假如你想像例子一样,传递一个对象到一个方法中,并由该方法修改对象。
4550
- 可以成功修改a
4651
```java
@@ -61,7 +66,6 @@ a.setXXX("XX");
6166
return a;//此时的a已经是修改后的值
6267
```
6368

64-
6569
要切记,这个Object一定要在调用方法前,就初始化好(new一个),然后再作为参数传进去,并且在方法中不能再初始化这个参数。这样,在方法中对该参数的修改,才会有效地修改到a这个变量
6670

6771

contents/java-operator.md

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,35 @@
11
##Java += 操作符实质
22

33
###问题
4-
直到今天,我都一直以为
4+
我之前以为
55
i += j 等同于 i = i + j;
66
但假设有:
7+
```java
78
int i = 5;
89
long j = 8;
10+
```
911
这时 i = i + j不能编译,但i += j却可以编译。这说明两者还是有差别的
1012
这是否意味着,i += j,实际是等同于 i= (type of i) (i + j)呢?
1113

1214
###回答
1315
这个问题,其实官方文档中已经解答了。 请看这里。[§15.26.2 Compound Assignment Operators](http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#15.26.2 )
16+
17+
1418
再照搬下官方文档的说明
19+
20+
1521
对复合赋值表达式来说,E1 op= E2(诸如i += j;i-=j等等),其实是等同于E1 = (T)((E1) op (E2)),其中,T是E1这个元素的类型。
22+
1623
举例来说,如下的代码
24+
```java
1725
short x = 3;
1826
x += 4.6;
19-
等于
27+
```
28+
等同于
29+
```java
2030
short x = 3;
2131
x = (short)(x + 4.6);
32+
```
2233

2334

2435
stackoverflow链接

contents/stringbuilder-and-stringbuffer.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
##StringBuilder和StringBuffer有哪些区别呢
22

3-
###最主要的区别,StringBuffer的实现使用了synchronized(锁),而StringBuilder没有。
3+
###最主要的区别,StringBuffer的实现用了synchronized(锁),而StringBuilder没有。
44

55
因此,StringBuilder会比StringBuffer快。
66

@@ -9,10 +9,10 @@
99
- 不需要考虑线程安全问题,
1010
- JRE是1.5+
1111

12-
可以用StringBuilder,
13-
反之,请用StringBuffer。
12+
可以用StringBuilder,反之,请用StringBuffer。
1413

1514
性能测试例子:
15+
1616
如下这个例子,使用StringBuffer,耗时2241ms,而StringBuilder是753ms
1717
```java
1818
public class Main {

contents/using-java-net-urlconnection-to-fire-and-handle-http-requests.md

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ URLEncoder.encode(param1, charset),
1515
URLEncoder.encode(param2, charset));
1616
```
1717
请求参数必须是name=value这样的格式,每个参数间用&连接。一般来说,你还得用 [URLEncoder#encode()](http://docs.oracle.com/javase/6/docs/api/java/net/URLEncoder.html)对参数做[编码](http://en.wikipedia.org/wiki/Percent-encoding)
18+
1819
上面例子还用到了String#format(),这只是为了方便,我更喜欢用这个方式来完成string的拼接。
1920

2021
###发送一个[HTTP GET](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3)请求(可选:带上参数)
@@ -43,13 +44,16 @@ InputStream response = connection.getInputStream();
4344
```
4445

4546
提醒:
47+
4648
当你要提交一个HTML表单时,务必要把<input type="hidden"这类元素的值,以name=value的形式也一并提交。另外,还有<input type="submit">这类元素,也是如此。因为,通常服务端也需要这个信息,来确认哪一个按钮触发了这个提交动作。
4749

4850
也可以使用[HttpURLConnection](http://docs.oracle.com/javase/6/docs/api/java/net/HttpURLConnection.html) 来代替[URLConnection](http://docs.oracle.com/javase/6/docs/api/java/net/URLConnection.html) ,然后调用[HttpURLConnection#setRequestMethod()](http://docs.oracle.com/javase/6/docs/api/java/net/HttpURLConnection.html#setRequestMethod%28java.lang.String%29)来将请求设为POST类型。
51+
4952
```java
5053
HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection();
5154
httpConnection.setRequestMethod("POST");
5255
```
56+
5357
同样的,如果服务端是[HttpServlet](http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServlet.html),将会触发它的[doPost()](http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServlet.html#doPost%28javax.servlet.http.HttpServletRequest,%20javax.servlet.http.HttpServletResponse%29)方法,可以通过[HttpServletRequest#getParameter()](http://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#getParameter%28java.lang.String%29)获取post参数
5458

5559
###真正触发HTTP请求的发送

contents/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
##重写(Override)equlas和hashCode方法时应考虑的问题
22

33
###理论上讲(编程语言、数学层面)
4-
equals() 定义了对象的相等关系(自反性、对称性、传递性)(有点抽象,更详细说明,请参考javadoc) 。
4+
equals() 定义了对象的相等关系(自反性、对称性、传递性)(有点抽象,更详细说明,请参考[javadoc](http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object))) 。
55
另外,它还具有一致性(也就是说,如果一个对象没有修改,那么对象的equals方法,应总是返回相同的值),此外,o.equals(null)应当总是返回false。
6-
hashCode()(javadoc)也必须具备一致性的(也就是说,如果equal的结果没有变,那么hashcode()也应总是返回相同的值)
6+
hashCode()([javadoc](http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()))也必须具备一致性的(也就是说,如果equal的结果没有变,那么hashcode()也应总是返回相同的值)
77

88
总的来说,这两个方法的关系:
99

1010
**假如a.equals(b),那么a.hashCode() 应等于b.hashCode()**
1111

1212
###实践上讲
13+
1314
**如果你重写了其中一个方法,那么务必重写另外一个方法**
1415

1516
equals()和hashCode()所计算的属性集(set of fields)应当是一样的
@@ -48,6 +49,8 @@ public class Person {
4849
2. 如果你是用eclipse,可以在代码编辑区右键,然后选择 Source > Generate hashCode() and equals()
4950

5051
**另外请记得**
52+
53+
5154
当你使用一些基于Hash的 Collection 、 Map,例如HashSet, LinkedHashSet, HashMap, Hashtable, 、WeakHashMap等。在键值对被放到集合中之后,请确保其key值所对应的hashCode()是保持不变的。比较可靠的一个办法,是保持这些key是不可变的,这也能带来不少好处
5255

5356

contents/when-to-use-linkedlist-over-arraylist.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
###耗时上各有优缺点。ArrayList稍有优势
66
List只是一个接口,而LinkedList、ArrayList是List的不同实现。LinkedList的模型是双向链表,而ArrayList则是动态数组
7-
首先对比下常用操作的算法复杂度
87

8+
首先对比下常用操作的算法复杂度
99
#####LinkedList
1010
- get(int index) : O(n)
1111
- add(E element) : O(1)

0 commit comments

Comments
 (0)