Java编程:常见问题汇总

欢迎进入Java社区论坛,与200万技术人员互动交流 >>进入

正确的写法:

    Mapmap=newHashMap(1+(int)(collection.size()/0.75));

对Hashtable, HashMap 和 HashSet了解不够

这里主要需要了解HashMap和Hashtable的内部实现上, 它们都使用Entry包装来封装key/value, Entry内部除了要保存Key/Value的引用, 还需要保存hash桶中next Entry的应用, 因此对内存会有不小的开销, 而HashSet内部实现其实就是一个HashMap. 有时候IdentityHashMap可以作为一个不错的替代方案. 它在内存使用上更有效(没有用Entry封装, 内部采用Object[]). 不过需要小心使用. 它的实现违背了Map接口的定义. 有时候也可以用ArrayList来替换HashSet.

这一切的根源都是由于JDK内部没有提供一套高效的Map和Set实现。

对List的误用

建议下列场景用Array来替代List:

list长度固定,比如一周中的每一天 对list频繁的遍历,比如超过1w次 需要对数字进行包装(主要JDK没有提供基本类型的List)

比如下面的代码。

错误的写法:

    List<Integer>codes=newArrayList<Integer>(); codes.add(Integer.valueOf(10)); codes.add(Integer.valueOf(20)); codes.add(Integer.valueOf(30)); codes.add(Integer.valueOf(40));

正确的写法:

    int[]codes={10,20,30,40};

错误的写法:

    //horriblyslowandamemorywasteriflhasafewthousandelements(tryityourself!) List<Mergeable>l=…; for(inti=0;i<l.size()-1;i++){ Mergeableone=l.get(i); Iterator<Mergeable>j=l.iterator(i+1);//memoryallocation! while(j.hasNext()){ Mergeableother=l.next(); if(one.canMergeWith(other)){ one.merge(other); other.remove(); } } }

正确的写法:

    //quitefastandnomemoryallocation Mergeable[]l=…; for(inti=0;i<l.length-1;i++){ Mergeableone=l[i]; for(intj=i+1;j<l.length;j++){ Mergeableother=l[j]; if(one.canMergeWith(other)){ one.merge(other); l[j]=null; } } }

实际上Sun也意识到这一点, 因此在JDK中, Collections.sort()就是将一个List拷贝到一个数组中然后调用Arrays.sort方法来执行排序。

用数组来描述一个结构

错误用法:

    /** *@returns[1]:Location,[2]:Customer,[3]:Incident */ Object[]getDetails(intid){…

这里用数组+文档的方式来描述一个方法的返回值. 虽然很简单, 但是很容易误用, 正确的做法应该是定义个类。

正确的写法:

    DetailsgetDetails(intid){…} privateclassDetails{ publicLocationlocation; publicCustomercustomer; publicIncidentincident; }

对方法过度限制

错误用法:

    publicvoidnotify(Personp){ … sendMail(p.getName(),p.getFirstName(),p.getEmail()); … } classPhoneBook{ Stringlookup(StringemployeeId){ Employeeemp=… returnemp.getPhone(); } }

第一个例子是对方法参数做了过多的限制, 第二个例子对方法的返回值做了太多的限制。

正确的写法:

    publicvoidnotify(Personp){ … sendMail(p); … } classEmployeeDirectory{ Employeelookup(StringemployeeId){ Employeeemp=… returnemp; } }

对POJO的setter方法画蛇添足

错误的写法:

    privateStringname; publicvoidsetName(Stringname){ this.name=name.trim(); } publicvoidStringgetName(){ returnthis.name; }

有时候我们很讨厌字符串首尾出现空格, 所以在setter方法中进行了trim处理, 但是这样做的结果带来的副作用会使getter方法的返回值和setter方法不一致, 如果只是将JavaBean当做一个数据容器, 那么最好不要包含任何业务逻辑. 而将业务逻辑放到专门的业务层或者控制层中处理。

正确的做法:

    person.setName(textInput.getText().trim());

日历对象(Calendar)误用

错误的写法:

    Calendarcal=newGregorianCalender(TimeZone.getTimeZone(“Europe/Zurich”)); cal.setTime(date); cal.add(Calendar.HOUR_OF_DAY,8); date=cal.getTime();

这里主要是对date, time, calendar和time zone不了解导致. 而在一个时间上增加8小时, 跟time zone没有任何关系, 所以没有必要使用Calendar, 直接用Date对象即可, 而如果是增加天数的话, 则需要使用Calendar, 因为采用不同的时令制可能一天的小时数是不同的(比如有些DST是23或者25个小时)

正确的写法:

    date=newDate(date.getTime()+8L*3600L*1000L);//add8hrs

TimeZone的误用

错误的写法:

    Calendarcal=newGregorianCalendar(); cal.setTime(date); cal.set(Calendar.HOUR_OF_DAY,0); cal.set(Calendar.MINUTE,0); cal.set(Calendar.SECOND,0); DatestartOfDay=cal.getTime();

这里有两个错误, 一个是没有没有将毫秒归零, 不过最大的错误是没有指定TimeZone, 不过一般的桌面应用没有问题, 但是如果是服务器端应用则会有一些问题, 比如同一时刻在上海和伦敦就不一样, 因此需要指定的TimeZone.

正确的写法:

    Calendarcal=newGregorianCalendar(user.getTimeZone()); cal.setTime(date); cal.set(Calendar.HOUR_OF_DAY,0); cal.set(Calendar.MINUTE,0); cal.set(Calendar.SECOND,0); cal.set(Calendar.MILLISECOND,0); DatestartOfDay=cal.getTime();

时区(Time Zone)调整的误用

错误的写法:

    publicstaticDateconvertTz(Datedate,TimeZonetz){ Calendarcal=Calendar.getInstance(); cal.setTimeZone(TimeZone.getTimeZone(“UTC”)); cal.setTime(date); cal.setTimeZone(tz); returncal.getTime(); }

[1][2][3][4]

游手好闲会使人心智生锈

Java编程:常见问题汇总

相关文章:

你感兴趣的文章:

标签云: