Home  >  Article  >  Java  >  The 10 most popular java questions on stackoverflow

The 10 most popular java questions on stackoverflow

伊谢尔伦
伊谢尔伦Original
2016-11-30 11:39:091163browse

1. Why does subtracting two (1927) times get a strange result?

  (3623 likes)

   If you execute the following program, the program parses two date strings separated by 1 second and compares:

public static void main(String[] args) throws ParseException {
    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
    String str3 = "1927-12-31 23:54:07";  
    String str4 = "1927-12-31 23:54:08";  
    Date sDt3 = sf.parse(str3);  
    Date sDt4 = sf.parse(str4);  
    long ld3 = sDt3.getTime() /1000;  
    long ld4 = sDt4.getTime() /1000;
    System.out.println(ld4-ld3);
}

  The output is:

353

  Why ld4-ld3 is not 1 (because I want these two The time difference is one second), but 353?

 If you add one second to each date string:

String str3 = "1927-12-31 23:54:08";  
String str4 = "1927-12-31 23:54:09";

 The result of ld4-ld3 is 1.

sun.util.calendar.ZoneInfo[id="Asia/Shanghai",
offset=28800000,dstSavings=0,
useDaylight=false,
transitions=19,
lastRule=null]
Locale(Locale.getDefault()): zh_CN

Solution

 This is the Shanghai time zone, there is a change on December 31st.

 Check this website to learn the details of Shanghai’s time zone changes in 1927. Basically at midnight at the end of 1927, it will always be set back 5 minutes and 52 seconds. So "1927-12-31 23:54:08" actually happens twice, and it looks like Java parsed the latter time as a local date and time causing the difference.

 2. Is Java "pass by reference" or "pass by value"?

  (2480 likes)

  I always thought that Java was pass-by-reference; however, I read a bunch of blogs (such as this one) that claimed otherwise. I don't think I understand the difference between them.

Give me an explanation?

 Solution

 Java has always been about passing by value. Unfortunately, they decided to call pointers references, so newcomers are always confused. Because these references are also passed by value.

  3. A question about Java += operator

   (2223 likes)

  Until today I think this example:

i += j;

  is just a shorthand:

i = i + j;

  But if you do:

int i = 5;
long j = 8;

  However i = i + j; cannot be compiled, but i += j; can be compiled.

 This means i += j; is it actually the abbreviation of i = (type of i) (i + j)?

 Solution

 There are always people asking this kind of questions, and JLS has the answers. See §15.26.2 Compound assignment operators. Excerpt:

E1 op = The compound assignment expression of type E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1. The difference is that E1 is only calculated once.

An example, quoted from §15.26.2

[...] The following code is correct:

short x = 3;
x += 4.6;

The result of x is equal to 7 because it is equivalent to:

short x = 3;
x = (short)(x + 4.6);

In other words, your assumption is correct.

 4. What is the difference between HashMap and Hashtable?

 (1769 likes)

 What is the difference between HashMap and Hashtable in Java?

 Which one is more efficient to use in non-multithreaded applications?

 Solution

 There are several differences between HashMap and HashTable in Java:

Hashtable is synchronized, but HashMap is not. This makes HashMap more suitable for non-multithreaded applications, because non-synchronized objects usually perform more efficiently than synchronized objects.

Hashtable does not allow null values ​​and keys. HashMap allows a null key and a NULL value.

A subclass of HashMap is LinkedHashMap. So, if you want to predict the iteration order (the default insertion order), just convert the HashMap into a LinkedHashMap. It's not that simple with Hashtable.

Since synchronization is not a problem for you, I recommend using HashMap. If synchronization is an issue, you might also look at ConcurrentHashMap.

 5. (How to) Read or convert an InputStream into a String

  (1724 likes)

  If you have a java.io.InputStream object, how to process this object and generate a string?

 Suppose I have an InputStream object that contains text data, and I want to convert it into a string (for example, so that I can write the contents of the stream to a log file).

 What is the easiest way to convert InputStream into String?

 Solution

 A good way is to use the Apache commons IOUtils library to copy the InputStream to a StringWriter, something like this:

StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, encoding);
String theString = writer.toString();

 Or even

// NB: does not close inputStream, you can use IOUtils.closeQuietly for that
// 注意:不关闭inputStream,你可以使用 IOUtils.closeQuietly
String theString = IOUtils.toString(inputStream, encoding);

 Or, if you don’t want to mix Stream and Writer, you can use ByteArrayOutputStream.

 6. Why does Java prefer to use char[] instead of String for passwords?

 (1574 likes)

  在Swing中,密码字段有一个getPassword()(返回 char数组)方法而不是通常的getText()(返回String)方法。同样的,我遇到过一个建议,不要使用 String 来处理密码。

  为什么String涉及到密码时,它就成了一个安全威胁?感觉使用char数组不太方便。

  解决方案

  String是不可变的。这意味着一旦创建了字符串,如果另一个进程可以进行内存转储,在GC发生前,(除了反射)没有方法可以清除字符串数据。

  使用数组操作完之后,可以显式地清除数据:可以给数组赋任何值,密码也不会存在系统中,甚至垃圾回收之前也是如此。

  所以,是的,这是一个安全问题 – 但是即使使用了char数组,仅仅缩小了了攻击者有机会获得密码的窗口,它值针对制定的攻击类型。

 7、遍历HashMap的最佳方法

  (1504个赞)

  遍历HashMap中元素的最佳方法是什么?

  解决方案

  这样遍历entrySet:

public static void printMap(Map mp) {
    Iterator it = mp.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry pair = (Map.Entry)it.next();
        System.out.println(pair.getKey() + " = " + pair.getValue());
        it.remove(); // avoids a ConcurrentModificationException
    }
}

  更多请查阅Map。

  8、(如何)从数组创建ArrayList

  (1468个赞)

  我有一个数组,初始化如下:

Element[] array = {new Element(1), new Element(2), new Element(3)};

  我希望将这个数组转化成一个ArrayList类的对象。

  解决方案

new ArrayList<Element>(Arrays.asList(array))

 9、产生一个Java的内存泄露

  (1478个赞)

  我有过一个面试,被问到如何产生一个Java内存泄露。不用说,我感到相当傻,甚至如何产生一个的线索都没有。

  那么怎么才能产生一个内存泄露呢?

  解决方案

  在纯Java中,有一个很好的方式可以产生真正的内存泄露(通过执行代码使对象不可访问但仍存在于内存中):

应用产生一个长时间运行的线程(或者使用一个线程池加速泄露)。

线程通过一个(可选的自定义)类加载器加载一个类。

该类分配大内存(例如,new byte[1000000]),赋值给一个强引用存储在静态字段中,再将它自身的引用存储到ThreadLocal中。分配额外的内存是可选的(泄露类实例就够了),但是这样将加速泄露工作。

线程清除所有自定义类的或者类加载器载入的引用。

重复上面步骤。

  这样是有效的,因为ThreadLocal持有对象的引用,对象持有类的引用,接着类持有类加载器的引用。反过来,类加载器持有所有已加载类的引用。这会使泄露变得更加严重,因为很多JVM实现的类和类加载都直接从持久带(permgen)分配内存,因而不会被GC回收。

  10、使用Java在一个区间内产生随机整数数

  (1422个赞)

  我试着使用Java生成一个随机整数,但是随机被指定在一个范围里。例如,整数范围是5~10,就是说5是最小的随机值,10是最大的。5到10之间的书也可以是生成的随机数。

  解决方案

  标准的解决方式(Java1.7 之前)如下:

import java.util.Random;
public static int randInt(int min, int max) {
    Random rand;
    int randomNum = rand.nextInt((max - min) + 1) + min;
    return randomNum;
}

  请查看相关的JavaDoc。在实践中,java.util.Random 类总是优于 java.lang.Math.random()。

  特别是当标准库里有一个直接的API来完成这个工作,就没有必要重复制造轮子了。


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn