在2009年的JavaOne大会上,Joshua Bloch和Neal Gafter又为我们带来的7道谜题,挺有意思的。大家不妨看看。
摘自:
Return of the Puzzlers: Schlock and Awe
Joshua Bloch, Google, Inc.; Neal Gafter, Microsoft
http://developers.sun.com/learning/javaoneonline/sessions/2009/pdf/TS-5186.pdf
1.Life's Persistent Questionspublic class SimpleQuestion {    static boolean yesOrNo(String s) {
        s = s.toLowerCase();
        if (s.equals("yes") || s.equals("y") || s.equals("t")) {
            s = "true";
        }
        return Boolean.getBoolean(s);
    }    public static void main(String[] args) {
        System.out.println(yesOrNo("true") + " " + yesOrNo("Yes"));
    }
}问题:程序打印什么?
如果熟悉Boolean.getBoolean()这个方法的话,应该不会出错。方法的功能参考文档。2.Instruments of Tortue
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;public class InstrumentedHashSet<E> extends HashSet<E> {
    private int addCount = 0;
    @Override
    public boolean add(E e){
        addCount++;
        return super.add(e);
    }    @Override
    public boolean addAll(Collection<? extends E> c){
        addCount += c.size();
        return super.addAll(c);
    }    public static void main(String[] args) {
        InstrumentedHashSet<String> s = new InstrumentedHashSet<String>();
        s.addAll(Arrays.asList("Accordion","Banjo","Kazoo"));
        System.out.println(s.addCount);
    }
}
问题:打印结果是什么?这个看第一遍可能会出错,不过也算容易理解。3.Iterator Titillatorimport java.util.Iterator;
import java.util.NoSuchElementException;public abstract class AbstractIterator<T> implements Iterator<T> {    T next = nextElement();    public boolean hasNext() {
        return next != null;
    }    public T next() {
        if (next == null) {
            throw new NoSuchElementException();
        }
        T result = next;
        next = nextElement();
        return result;
    }    public void remove() {
        throw new UnsupportedOperationException();
    }    protected abstract T nextElement();    private static Iterator<Character> test(final String s) {
        return new AbstractIterator<Character>() {            private int cursor = 0;            protected Character nextElement() {
                return cursor == s.length() ? null : s.charAt(cursor++);
            }
        };
    }    public static void main(String[] args) {
        for (Iterator<Character> i = test("OPS"); i.hasNext();) {
            System.out.print(i.next());
        }
    }
}
问题:输出结果是什么?理解如何正确的设计Iterator。4.Search for the One
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Searching {
    public static void main(String[] args) {
        String[] strings = { "0", "1", "2", "3", "4", "5"};        List<Integer> integers = new ArrayList<Integer>();
        for(String s : strings){
            integers.add(Integer.valueOf(s));
        }        System.out.println(Collections.binarySearch(integers, 1,cmp));
    }    static Comparator<Integer> cmp = new Comparator<Integer>(){
        public int compare(Integer i,Integer j){
            return i<j?-1:(i==j?0:1);
        }
    };
}
问题:打印结果是什么?如果看过《Java Puzzlers》这本书的话应该容易发现问题。5.Cogito Ergo Sum
import java.util.LinkedHashMap;
import java.util.Map;public enum RomanNumeral {    I(1), V(5), X(10), L(50), C(100), D(500), M(1000);
    private static Map<Integer, RomanNumeral> map = new LinkedHashMap<Integer, RomanNumeral>();
    public final int val;    RomanNumeral(int val) {
        this.val = val;
        storeInMap();
    }    private void storeInMap() {
        map.put(val, this);
    }    public static RomanNumeral fromInt(int val) {
        return map.get(val);
    }    public static void main(String[] args) {
        int sum = 0;
        for (int i = 0; i < 1000; i++) {
            if (fromInt(i) != null) {
                sum += i;
            }
        }
        System.out.println(sum);
    }
}
问题:打印结果是什么?如果理解java加载类和创建对象的顺序的话这个问题容易理解。6.Thread Friendly
public class ThreadFriendly {
    ThreadLocal<Value> threadLocalPart = new ThreadLocal<Value>();
    class Value{
        final int i;
        Value(int i){
            this.i = i;
        }
    }
    
    ThreadFriendly setThreadVal(int i){
        threadLocalPart.set(new Value(i));
        return this;
    }
    
    int getThreadVal(){
        return threadLocalPart.get().i;
    }
    
    public static void main(String[] args) {
        int sum = 0;
        for(int i = -500000;i<=500000;i++){
            sum+= new ThreadFriendly().setThreadVal(i).getThreadVal();
        }
        System.out.println(sum);
    }
}
问题:打印结果是什么?理解内部类和ThreadLocal。7.When Words Collidepublic class PrintWords {
    public static void main(String[] args) {
        System.out.println(
            Words.FIRST + " " + Words.SECOND + " " + Words.THIRD
        );
    }
}public class Words{
    public static final String FIRST = "the";
    public static final String SECOND = null;
    public static final String THIRD = "set";
}编译PrintWords.java文件。
修改Words.java文件为public class Words{
    public static final String FIRST = "physics";
    public static final String SECOND = "chemistry";
    public static final String THIRD = "biology";
}问题:再次编译运行PrintWords.java,打印结果是什么?需要了解常量折叠现象,理解什么是常量。

解决方案 »

  1.   

    正真考验了java的功底,很不错的
      

  2.   

    嗯,确实是有深度
    第一题getBoolean(String name)
    当且仅当以参数命名的系统属性存在,且等于 "true" 串时,返回为 true。这样写的话,返回true了    public static void main(String[] args) {
            Properties   p   =   System.getProperties();   
            p.setProperty("test",   "true");   
            System.out.println("Boolean.getBoolean():"   +   Boolean.getBoolean("test"));
        }
      

  3.   

    别人都知道Boolean.getBoolean(s)查看的是系统变量值。
      

  4.   

    这个也是意外一个学弟问过的,那时候才查记住的。
    java类那么多肯定得查呀,我看了你给出的第7个例子,我没明白什么意思。
      

  5.   

    《Java Puzzlers》没有看过,不过我估计问题出在i==j上。
      

  6.   

    《Java Puzzlers》我借过 可惜还掉了╮(╯_╰)╭
      

  7.   

    你不是不做java了吗,怎么还这么关注java。
      

  8.   

    学习了 看了几个问题 觉得都是对JAVA中容易忽视的问题但是又比较显眼的问题的考察把
       通常这种情况在自己实践的过程种中会慢慢积累,每次遇到一个去翻翻书看看,牢记, 做成自己的DEMO 
       用处很大的,我时新手,象这种“偏”的小知识点,我每次遇到我都收集做成DEMO
      

  9.   

    分析和解答可以参考
    原作者的演示材料:
    http://developers.sun.com/learning/javaoneonline/sessions/2009/pdf/TS-5186.pdf
    或者我的分析总结:
    http://blog.csdn.net/ZangXT/archive/2009/07/29/4391628.aspx
      

  10.   

    第7题是啥意思啊??
    为啥重新编译 PrintWords 输出没有变化??这个可以使用 常量堆叠来理解;因为 PrintWords.class 此时存放的是 the null set.但重新 编译 Words 为啥能够使得 PrintWords的执行结果产生变化啊??此时 PrintWords.class 根本没有任何变化的(因为俺一直用UltraEdit打开着,没有任何更新提示).
      

  11.   

    俺使用的 NetBeans 6.1...JDK1.5..
      

  12.   

    果然使用了很多JDK5以后的新特性,不错,值得做一做思考思考,谢谢楼主分享!
      

  13.   

    这个...,系统值除了Properties的setProperty方法,还有什么办法set进去吗?既然是系统变量应该是系统初始化就应该有的值吧,怎么进去的?
      

  14.   

    1年没来csdn了,ZangXT大侠还是这么的活跃,留个记号回去慢慢看
      

  15.   

    [Quote=引用 67 楼 jackson416 的回复:]
    学习.
      

  16.   

    第一题
     false false
    第7题
    the chemistry set  
      

  17.   

    七个题都作了一遍, 很有收获。现在还没有看题解,说一下我的看法。每个题目我都没有答对。
    第1题:这个题没意思,反正我没有这样用过Boolean,不知大伙用过每。
    第2题:多态,陷阱题目
    第3题:明知道输出的是OOPS,但是还是不知道怎么输出的,debug了半天,因为用了匿名内部类和泛型,也不好调试,但最后还是想明白了:先初始化父类成员next. 调用了子类的nextElement方法,虽然nextElement更改了子类的成员cursor,但是在紧接着初始化子类成员的时候,cursor又还原了。
    给个例子解释一下这个问题:
    public abstract class Test {
    int a = change();
    public abstract int change();
    }
    //----------
    public class Test1 extends Test{
    int b = 111;
    public int change() {
    b = 333;
    return 456;//a
    }
    public void change1(){
    b = 888;
    }
    public static void main(String[] args){
    Test1 t = new Test1();
    System.out.println(t.b);
    t.change1();
    System.out.println(t.b);
    }
    }第4题:愣是没看明白,直到看到大家的提示;不过倒是了解了一下Collections的binarySearch方法。
    第5题:枚举的, 没看。
    第6题:以前写过Hibernate SessionFactory,所以了解一点ThreadLocal. i=500000会出错.i=5000似乎可以.
    第7题:不了解有什么变化.