??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产高清视频,91久久亚洲国产成人精品性色,亚洲av无码专区国产不乱码 http://www.tkk7.com/redcoatjk/category/48589.html万物皆对?万事归节?/description>zh-cnFri, 27 May 2011 21:36:58 GMTFri, 27 May 2011 21:36:58 GMT60[转]java中hashcode()和equals()的详?/title><link>http://www.tkk7.com/redcoatjk/archive/2011/05/27/351200.html</link><dc:creator>redcoatjk</dc:creator><author>redcoatjk</author><pubDate>Fri, 27 May 2011 10:15:00 GMT</pubDate><guid>http://www.tkk7.com/redcoatjk/archive/2011/05/27/351200.html</guid><wfw:comment>http://www.tkk7.com/redcoatjk/comments/351200.html</wfw:comment><comments>http://www.tkk7.com/redcoatjk/archive/2011/05/27/351200.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/redcoatjk/comments/commentRss/351200.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/redcoatjk/services/trackbacks/351200.html</trackback:ping><description><![CDATA[摘自:<div>http://www.iteye.com/topic/257191</div><br />-----------------<br /><div>今天下午研究了半天hashcode()和equals()ҎQ终于有了一点点的明白,写下来与大家分nQzhaoxudong 2008.10.23?1.36Q? <br />1. 首先equals()和hashcode()q两个方法都是从objectcMl承q来的? <br />equals()Ҏ在objectcM定义如下Q? <br />  public boolean equals(Object obj) { <br />return (this == obj); <br />} <br />很明显是对两个对象的地址D行的比较Q即比较引用是否相同Q。但是我们必需清楚Q当String 、Math、还有Integer、Double。。。。等q些装cd使用equals()ҎӞ已经覆盖了objectcȝequalsQ)Ҏ。比 如在StringcM如下Q? <br />  public boolean equals(Object anObject) { <br />if (this == anObject) { <br />    return true; <br />} <br />if (anObject instanceof String) { <br />    String anotherString = (String)anObject; <br />    int n = count; <br />    if (n == anotherString.count) { <br />char v1[] = value; <br />char v2[] = anotherString.value; <br />int i = offset; <br />int j = anotherString.offset; <br />while (n-- != 0) { <br />    if (v1[i++] != v2[j++]) <br />return false; <br />} <br />return true; <br />    } <br />} <br />return false; <br />} <br />很明显,q是q行的内Ҏ较,而已l不再是地址的比较。依ơ类推Double、Integer、Math。。。。等{这些类都是重写了equals()Ҏ的,从而进行的是内容的比较。当然了基本cd是进行值的比较Q这个没有什么好说的? <br />我们q应该注意,Java语言对equals()的要求如下,q些要求是必遵循的Q? <br />• 对称性:如果x.equals(y)q回?#8220;true”Q那么y.equals(x)也应该返回是“true”? <br />• 反射性:x.equals(x)必须q回?#8220;true”? <br />• cL性:如果x.equals(y)q回?#8220;true”Q而且y.equals(z)q回?#8220;true”Q那么z.equals(x)也应该返回是“true”? <br />• q有一致性:如果x.equals(y)q回?#8220;true”Q只要x和y内容一直不变,不管你重复x.equals(y)多少ơ,q回都是“true”? <br />• M情况下,x.equals(null)Q永q返回是“false”Qx.equals(和x不同cd的对?永远q回?#8220;false”? <br />以上q五Ҏ重写equals()ҎӞ必须遵守的准则,如果q反会出现意想不到的l果Q请大家一定要遵守? <br />2. 其次是hashcode() ҎQ在objectcM定义如下Q? <br />  public native int hashCode(); <br />说明是一个本地方法,它的实现是根据本地机器相关的。当然我们可以在自己写的cM覆盖hashcode()ҎQ比如String?Integer、Double。。。。等{这些类都是覆盖了hashcode()Ҏ的。例如在StringcM定义的hashcode()Ҏ如下Q? <br />    public int hashCode() { <br />int h = hash; <br />if (h == 0) { <br />    int off = offset; <br />    char val[] = value; <br />    int len = count; <br /> <br />            for (int i = 0; i < len; i++) { <br />                h = 31*h + val[off++]; <br />            } <br />            hash = h; <br />        } <br />        return h; <br />} <br />解释一下这个程序(String的API中写刎ͼQ? <br />s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] <br />使用 int 法Q这?s[i] 是字W串的第 i 个字W,n 是字W串的长度,^ 表示求幂。(I字W串的哈希码?0。) <br /> <br />3.q里我们首先要明白一个问题: <br />equals()相等的两个对象,hashcode()一定相{; <br />equalsQ)不相{的两个对象Q却q不能证明他们的hashcode()不相{。换句话_equals()Ҏ不相{的两个对象Qhashcode()有可能相{。(我的理解是由于哈希码在生成的时候生冲H造成的)? <br />反过来:hashcode()不等Q一定能推出equals()也不{;hashcode()相等Qequals()可能相等Q也可能不等。解?下第3点的使用范围Q我的理解是在object、String{类中都能用。在objectcMQhashcode()Ҏ是本地方法,q回的是对象?地址|而objectcM的equals()Ҏ比较的也是两个对象的地址|如果equals()相等Q说明两个对象地址g相等Q当?hashcode()也就相等了;在StringcMQequals()q回的是两个对象内容的比较,当两个对象内容相{时Q? <br />Hashcode()ҎҎStringcȝ重写Q第2炚w面已l分析了Q代码的分析Q也可知道hashcode()q回l果也会相等。以此类 推,可以知道Integer、Double{封装类中经q重写的equals()和hashcode()Ҏ也同样适合于这个原则。当然没有经q重写的 c,在承了objectcȝequals()和hashcode()Ҏ后,也会遵守q个原则? <br /> <br />4.谈到hashcode()和equals()׃能不说到hashset,hashmap,hashtable中的使用Q具体是怎样呢,L如下分析Q? <br />Hashset是承Set接口QSet接口又实现Collection接口Q这是层ơ关pR那么hashset是根据什么原理来存取对象的呢Q? <br />在hashset中不允许出现重复对象Q元素的位置也是不确定的。在hashset中又是怎样判定元素是否重复的呢Q这是问题的关键所在,l过一下午的查询求证终于获得了一点启C,和大家分享一下,在java的集合中Q判断两个对象是否相{的规则是: <br />1)Q判断两个对象的hashCode是否相等 <br />      如果不相{,认ؓ两个对象也不相等Q完? <br />      如果相等Q{?) <br />Q这一点只是ؓ了提高存储效率而要求的Q其实理Z没有也可以,但如果没有,实际使用时效率会大大降低Q所以我们这里将其做为必需的。后面会重点讲到q个问题。) <br />2)Q判断两个对象用equalsq算是否相等 <br />      如果不相{,认ؓ两个对象也不相等 <br />      如果相等Q认Z个对象相{(equals()是判断两个对象是否相{的关键Q? <br />Z么是两条准则Q难道用W一条不行吗Q不行,因ؓ前面已经说了Qhashcode()相等Ӟequals()Ҏ也可能不{,所以必ȝW?条准则进行限Ӟ才能保证加入的ؓ非重复元素? <br />比如下面的代码: <br /> <br />public static void main(String args[]){ <br />String s1=new String("zhaoxudong"); <br />String s2=new String("zhaoxudong"); <br />System.out.println(s1==s2);//false <br />System.out.println(s1.equals(s2));//true <br />System.out.println(s1.hashCode());//s1.hashcode(){于s2.hashcode() <br />System.out.println(s2.hashCode()); <br />Set hashset=new HashSet(); <br />hashset.add(s1); <br />hashset.add(s2); <br />/*实质上在ds1,s2Ӟq用上面说到的两点准则,可以知道hashset认ؓs1和s2是相{的Q是在添加重复元素,所以让s2覆盖了s1;*/ <br />Iterator it=hashset.iterator(); <br />            while(it.hasNext()) <br />            { <br />             System.out.println(it.next()); <br />            } <br />最后在while循环的时候只打印Z一?#8221;zhaoxudong”? <br />输出l果为:false <br />            true <br />            -967303459 <br />            -967303459 <br />q是因ؓStringcdl重写了equals()Ҏ和hashcode()ҎQ所以在Ҏ上面的第1.2条原则判定时Qhashset认ؓ它们是相{的对象Q进行了重复d? <br />但是看下面的E序Q? <br />import java.util.*; <br />public class HashSetTest <br />{ <br />   public static void main(String[] args) <br />    { <br />                 HashSet hs=new HashSet(); <br />                 hs.add(new Student(1,"zhangsan")); <br />                 hs.add(new Student(2,"lisi")); <br />                 hs.add(new Student(3,"wangwu")); <br />                 hs.add(new Student(1,"zhangsan")); <br />  <br />                 Iterator it=hs.iterator(); <br />                 while(it.hasNext()) <br />                 { <br />                        System.out.println(it.next()); <br />                 } <br />     } <br />} <br />class Student <br />   { <br />     int num; <br />     String name; <br />     Student(int num,String name) <br />                { <br />                this.num=num; <br />                 this.name=name; <br />                 } <br />              public String toString() <br />                { <br />                    return num+":"+name; <br />                 } <br />           }      <br />输出l果为: <br />                      1:zhangsan <br />                   1:zhangsan <br />                   3:wangwu <br />                   2:lisi <br />问题出现了,Z么hashsetd了相{的元素呢,q是不是和hashset的原则违背了呢?回答是:没有 <br />因ؓ在根据hashcode()对两ơ徏立的new Student(1,"zhangsan")对象q行比较Ӟ生成的是不同的哈希码|所以hashset把他当作不同的对象对待了Q当然此时的 equals()Ҏq回的g不等Q这个不用解释了吧)。那么ؓ什么会生成不同的哈希码值呢Q上面我们在比较s1和s2的时候不是生成了同样的哈希码 吗?原因在于我们自己写的Studentcdƈ没有重新自己的hashcode()和equals()ҎQ所以在比较Ӟ是承的objectcM?hashcode()ҎQ呵呵,各位q记得objectcM的hashcode()Ҏ比较的是什么吧Q! <br />它是一个本地方法,比较的是对象的地址Q引用地址Q,使用newҎ创徏对象Q两ơ生成的当然是不同的对象了(q个大家都能理解吧。。。)Q造成 的结果就是两个对象的hashcode()q回的g一栗所以根据第一个准则,hashset会把它们当作不同的对象对待,自然也用不着W二个准则进?判定了。那么怎么解决q个问题呢?Q? <br />{案是:在StudentcM重新hashcode()和equals()Ҏ? <br />例如Q? <br />  class Student <br />{ <br />int num; <br />String name; <br />Student(int num,String name) <br />{ <br />            this.num=num; <br />            this.name=name; <br />} <br />public int hashCode() <br />{ <br />            return num*name.hashCode(); <br />} <br />public boolean equals(Object o) <br />{ <br />            Student s=(Student)o; <br />            return num==s.num && name.equals(s.name); <br />} <br />public String toString() <br />{ <br />            return num+":"+name; <br />} <br />} <br />Ҏ重写的方法,即便两次调用了new Student(1,"zhangsan")Q我们在获得对象的哈希码ӞҎ重写的方法hashcode()Q获得的哈希码肯定是一LQ这一点应该没有疑问吧Q? <br />当然Ҏequals()Ҏ我们也可判断是相同的。所以在向hashset集合中添加时把它们当作重复元素看待了。所以运行修改后的程序时Q我们会发现q行l果是: <br />                      1:zhangsan <br />                   3:wangwu <br />                   2:lisi <br />可以看到重复元素的问题已l消除? <br />关于在hibernate的pojocMQ重新equals()和hashcode()的问题: <br />1)Q重ҎequalsQ重写hashCode只是技术要求(Z提高效率Q? <br />2)Qؓ什么要重写equals呢,因ؓ在java的集合框架中Q是通过equals来判断两个对象是否相{的 <br />3)Q在hibernate中,l常使用set集合来保存相兛_象,而set集合是不允许重复的。我们再来谈谈前面提到在向hashset集合中添加元素时,怎样判断对象是否相同的准则,前面说了两条Q其实只要重写equals()q一条也可以? <br />但当hashset中元素比较多Ӟ或者是重写的equals()Ҏ比较复杂Ӟ我们只用equals()Ҏq行比较判断Q效率也会非怽Q?所以引入了hashcode()q个ҎQ只是ؓ了提高效率,但是我觉得这是非常有必要的(所以我们在前面以两条准则来q行hashset的元素是否重?的判断)? <br />比如可以q样写: <br />public int hashCode(){ <br />   return  1;}//{h于hashcode无效 <br />q样做的效果是在比较哈希码的时候不能进行判断,因ؓ每个对象q回的哈希码都是1Q每ơ都必须要经q比较equals()Ҏ后才能进行判断是否重复,q当然会引v效率的大大降低? <br />我有一个问题,如果像前面提到的在hashset中判断元素是否重复的必要Ҏ是equals()ҎQ根据网上找到的观点Q,但是q里q没有涉及到关于哈希表的问题Q可是这个集合却叫hashsetQ这是ؓ什么?Q? <br />我想Q在hashmap,hashtable中的存储操作Q依焉守上面的准则。所以这里不再多说。这些是今天看书Q网上查询资料,自己ȝ出来 的,部分代码和语a是引qͼ但是千真万确是自己ȝ出来的。有错误之处和不详细不清楚的地方q请大家指出Q我也是初学者,所以难免会有错误的地方Q希望大 家共同讨论? </div><img src ="http://www.tkk7.com/redcoatjk/aggbug/351200.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/redcoatjk/" target="_blank">redcoatjk</a> 2011-05-27 18:15 <a href="http://www.tkk7.com/redcoatjk/archive/2011/05/27/351200.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java各种数据cd转换http://www.tkk7.com/redcoatjk/archive/2011/02/21/344756.htmlredcoatjkredcoatjkMon, 21 Feb 2011 05:34:00 GMThttp://www.tkk7.com/redcoatjk/archive/2011/02/21/344756.htmlhttp://www.tkk7.com/redcoatjk/comments/344756.htmlhttp://www.tkk7.com/redcoatjk/archive/2011/02/21/344756.html#Feedback0http://www.tkk7.com/redcoatjk/comments/commentRss/344756.htmlhttp://www.tkk7.com/redcoatjk/services/trackbacks/344756.html各种数字cd转换成字W串型:

String s = String.valueOf( value); // 其中 value ZQ意一U数字类型?

字符串型转换成各U数字类型:

String s = "169";
byte b = Byte.parseByte( s );
short t = Short.parseShort( s );
int i = Integer.parseInt( s );
long l = Long.parseLong( s );
Float f = Float.parseFloat( s );
Double d = Double.parseDouble( s );

数字cd与数字类对象之间的{换:

byte b = 169;
Byte bo = new Byte( b );
b = bo.byteValue();

short t = 169;
Short to = new Short( t );
t = to.shortValue();

int i = 169;
b = bo.byteValue();

short t = 169;
Short to = new Short( t );
t = to.shortValue();

int i = 169;
Integer io = new Integer( i );
i = io.intValue();

long l = 169;
Long lo = new Long( l );
l = lo.longValue();

float f = 169f;
Float fo = new Float( f );
f = fo.floatValue();

double d = 169f;
Double dObj = new Double( d );
d = dObj.doubleValue();


redcoatjk 2011-02-21 13:34 发表评论
]]>
[转]J2SE 5.0专题 ?语言Ҏ?/title><link>http://www.tkk7.com/redcoatjk/archive/2010/05/16/321093.html</link><dc:creator>redcoatjk</dc:creator><author>redcoatjk</author><pubDate>Sun, 16 May 2010 07:35:00 GMT</pubDate><guid>http://www.tkk7.com/redcoatjk/archive/2010/05/16/321093.html</guid><wfw:comment>http://www.tkk7.com/redcoatjk/comments/321093.html</wfw:comment><comments>http://www.tkk7.com/redcoatjk/archive/2010/05/16/321093.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/redcoatjk/comments/commentRss/321093.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/redcoatjk/services/trackbacks/321093.html</trackback:ping><description><![CDATA[概述<br /> J2SE(TM) 5.0引入了很多激q的语言元素变化Q这些变化或多或减M我们开发h员的一些编码负担,其中的大部分也必然会被应用到卛_发布?a target="_blank">J2EE</a>(TM) 5.0中。主要的新特性包括: <p>  · 泛型</p> <p>  · 增强的for循环</p> <p>  · 自动装箱和自动拆?/p> <p>  · cd安全的枚?/p> <p>  · 可变长度参数</p> <p>  · 静态引?/p> <p>  · 元数?注解)</p> <p>  · C风格的格式化输出</p> <p>  q当中,泛型、枚丑֒注解可能会占用较大的幅Q而其余的因ؓ用法直截了当Q抑或相对简单,我就E作介绍Q剩下的留给读者去思考、去探烦了?/p> <p>  1.4. 泛型</p> <p>  泛型q个题目相当大,大到完全可以p个话题写一本书。有关Java是否需要泛型和如何实现泛型的讨Z早就在JavaCqؓ传。终于,我们在J2SE(TM) 5.0中看C它。也许目前JavaҎ型的支持q算不上_理想Q但q一Ҏ的d也经以让我们欣喜一阵了?/p> <p>  在接下来的介l中Q我们会了解刎ͼJava的泛型虽然跟<a target="_blank">C++</a>的泛型看上去十分怼Q但其实有着相当大的区别Q有些细节的东西也相当复?臛_很多地方会跟我们的直觉背道而驰)。可以这栯Q泛型的引入在很大程度上增加了Java语言的复杂度Q对初学者尤其是个挑战。下面我们将一点一点往里挖?/p> <p>  首先我们来看一个简单的使用泛型cȝ例子Q?/p> <p> <strong>   </strong>ArrayList<Integer> aList = new ArrayList<Integer>(); <br />  <strong>   </strong>aList.add(new Integer(1)); <br />  <strong>   </strong>// ... <br />  <strong>   </strong>Integer myInteger = aList.get(0); </p> <p>  我们可以看到Q在q个单的例子中,我们在定义aList的时候指明了它是一个直接受Integercd的ArrayListQ当我们调用aList.get(0)Ӟ我们已经不再需要先昑ּ的将l果转换成IntegerQ然后再赋值给myInteger了。而这一步在早先的Java版本中是必须的。也怽在想Q在使用Collection时节U一些类型{换就是Java泛型的全部吗?q不止。单p个例子而言Q泛型至还有一个更大的好处Q那是使用了泛型的容器cd得更加健壮:早先QCollection接口的get()和Iterator接口的next()Ҏ都只能返回Objectcd的结果,我们可以把这个结果强制{换成MObject的子c,而不会有M~译期的错误Q但q显然很可能带来严重的运行期错误Q因为在代码中确定从某个Collection中取出的是什么类型的对象完全是调用者自p了算Q而调用者也许ƈ不清楚放qCollection的对象具体是什么类?q知道放进ȝ对象“应该”是什么类Q也不能保证攑ֈCollection的对象就一定是那个cȝ实例。现在有了泛型,只要我们定义的时候指明该Collection接受哪种cd的对象,~译器可以帮我们避免cM的问题溜C品中。我们在实际工作中其实已l看C太多的ClassCastExceptionQ不是吗?</p> <p>  泛型的用从q个例子看也是相当易懂。我们在定义ArrayListӞ通过cd后面?lt;>括号中的值指定这个ArrayList接受的对象类型。在~译的时候,q个ArrayList会被处理成只接受该类或其子类的对象,于是M试图其他类型的对象dq来的语句都会被~译器拒l?/p> <p>  那么泛型是怎样定义的呢?看看下面q一D늤例代码:(其中用E代替在实际中会使用的类名,当然你也可以使用别的名称Q习惯上在这里用大写的EQ表CCollection的元素?</p> <p> <strong>   </strong>public class TestGenerics<E> { <br />  <strong>   </strong>Collection<E> col; <br />  <strong>   </strong>public void doSth(E elem) { <br />  <strong>   </strong>col.add(elem); <br />  <strong>   </strong>// ... <br />  <strong>   </strong>} <br />  <strong>   </strong>} <br />  <strong>      </strong>在泛型的使用中,有一个很Ҏ有的误解Q那是既然Integer是从Objectz出来的,那么ArrayList<Integer>当然是ArrayList<Object>的子cR真的是q样吗?我们仔细想一惛_会发现这样做可能会带来的问题Q如果我们可以把ArrayList<Integer>向上转型为ArrayList<Object>Q那么在往q个转了型以后的ArrayList中添加对象的时候,我们岂不是可以添加Q何类型的对象Q因为Object是所有对象的公共父类Q?q显然让我们的ArrayList<Integer>失去了原本的目的。于是Java~译器禁止我们这样做。那既然是这PArrayList<Integer>以及ArrayList<String>、ArrayList<Double>{等有没有公q父类呢?有,那就是ArrayList<?>?在这里叫做通配W。我们ؓ了羃通配W所指代的范_通常也需要这样写QArrayList<? extends SomeClass>Q这样写的含义是定义q样一个类ArrayListQ比方说SomeClass有SomeExtendedClass1和SomeExtendedClass2q两个子c,那么ArrayList<? extends SomeClass>是如下几个cȝ父类QArrayList<SomeClass>、ArrayList<SomeExtendedClass1>和ArrayList<SomeExtendedClass2>?nbsp;<br /> <br />  <strong>      </strong>接下来我们更q一步:既然ArrayList<? extends SomeClass>是一个通配的公用父c,那么我们可不可以往声明为ArrayList<? extends SomeClass>的ArrayList实例中添加一个SomeExtendedClass1的对象呢Q答案是不能。甚至你不能dM对象。ؓ什么?因ؓArrayList<? extends SomeClass>实际上代表了所有ArrayList<SomeClass>、ArrayList<SomeExtendedClass1>和ArrayList<SomeExtendedClass2>三种ArrayListQ甚臛_括未知的接受SomeClass其他子类对象的ArrayList。我们拿C个定义ؓArrayList<? extends SomeClass>的ArrayList的时候,我们q不能确定这个ArrayList具体是用哪个类作ؓ参数定义的,因此~译器也无法让这D代码编译通过。D例来Ԍ如果我们惛_q个ArrayList中放一个SomeExtendedClass2的对象,我们如何保证它实际上不是其他的如ArrayList<SomeExtendedClass1>Q而就是这个ArrayList<SomeExtendedClass2>呢?Q还记得吗?ArrayList<Integer>qArrayList<Object>的子cR)怎么办?我们需要用泛型方法。泛型方法的定义cM下面的例子: <br />  <strong>   </strong>public static <T extends SomeClass> void add (Collection<T> c, T elem) { <br />  <strong>   </strong>c.add(elem); <br />  <strong>   </strong>} </p> <p>  其中T代表了我们这个方法期待的那个最l的具体的类Q相关的声明必须攑֜Ҏ{֐中紧靠返回类型的位置之前。在本例中,它可以是SomeClass或者SomeClass的Q何子c,其说?t entends SomeClass>攑֜void关键字之?只能攑֜q里)。这h们就可以让编译器信当我们试图添加一个元素到泛型的ArrayList实例中时Q可以保证类型安全?/p> <p>  Java泛型的最大特点在于它是在语言U别实现的,区别?a target="_blank">C#</a> 2.0中的CLRU别。这L做法使得JRE可以不必做大的调_~点是无法支持一些运行时的类型甄别。一旦编译,它就被写MQ能提供的动态能力相当弱?/p> <p>  个h认ؓ泛型是这ơJ2SE(TM) 5.0中引入的最重要的语a元素Q给Java语言带来的媄响也是最大。D个例子来Ԍ我们可以看到Q几乎所有的Collections API都被更新成支持泛型的版本。这样做带来的好处是显而易见的Q那是减少代码重复(不需要提供多个版本的某一个类或者接口以支持不同cȝ对象)以及增强代码的健壮?~译期的cd安全?。不q如何才能真正利用好q个Ҏ,其是如何实现自q泛型接口或类供他Z用,ƈ非那么显而易见了。让我们一起在使用中慢慢积累?/p> <p>  1.5. 增强的for循环</p> <p>  你是否已l厌倦了每次写for循环旉要写上那些机械的代码Q尤其当你需要遍历数l或者CollectionQ如Q?假设在Collection中储存的对象是Stringcd?</p> <p> <strong>   </strong>public void showAll (Collection c) { <br />  <strong>   </strong>for (Iterator iter = c.iterator(); iter.hasNext(); ) { <br />  <strong>   </strong>System.out.println((String) iter.next()); <br />  <strong>   </strong>} <br />  <strong>   </strong>} <br /> <br />  <strong>   </strong>public void showAll (String[] sa) { <br />  <strong>   </strong>for (int i = 0; i < sa.length; i++) { <br />  <strong>   </strong>System.out.println(sa[i]); <br />  <strong>   </strong>} <br />  <strong>   </strong>} </p> <p>  q样的代码不仅显得臃肿,而且Ҏ出错Q我x们大家在刚开始接触编E时Q尤其是C/C++和JavaQ可能多都犯过以下cM错误的一U或几种Q把for语句的三个表辑ּ序弄错;W二个表辑ּ逻辑判断不正?漏掉一些、多Z些、甚x循环);忘记Ud游标;在@环体内不心改变了游标的位置{等。ؓ什么不能让~译器帮我们处理q些l节??.0中,我们可以q样写:</p> <p> <strong>   </strong>public void showAll (Collection c) { <br />  <strong>   </strong>for (Object obj : c) { <br />  <strong>   </strong>System.out.println((String) obj); <br />  <strong>   </strong>} <br />  <strong>   </strong>} <br /> <br />  <strong>   </strong>public void showAll (String[] sa) { <br />  <strong>   </strong>for (String str : sa) { <br />  <strong>   </strong>System.out.println(str); <br />  <strong>   </strong>} <br />  <strong>   </strong>} </p> <p>  q样的代码显得更加清晰和z,不是?具体的语法很单:使用":"分隔开Q前面的部分写明从数l或Collection中将要取出的cdQ以及用的临时变量的名字,后面的部分写上数l或者Collection的引用。加上泛型,我们甚至可以把第一个方法变得更加漂亮:</p> <p> <strong>   </strong>public void showAll (Collection<String> cs) { <br />  <strong>   </strong>for (String str : cs) { <br />  <strong>   </strong>System.out.println(str); <br />  <strong>   </strong>} <br />  <strong>   </strong>} </p> <p>  有没有发玎ͼ当你需要将Collection<string>替换成String[]Q你所需要做的仅仅是单的把参数类?Collection<string>"替换?String[]"Q反q来也是一P你不完全需要改其他的东ѝ这在J2SE(TM) 5.0之前是无法想象的?/p> <p>  对于q个看上ȝ当方便的新语a元素Q当你需要在循环体中讉K游标的时候,会显得很别扭Q比方说Q当我们处理一个链表,需要更新其中某一个元素,或者删除某个元素等{。这个时候,你无法在循环体内获得你需要的游标信息Q于是需要回退到原先的做法。不q,有了泛型和增强的for循环Q我们在大多数情况下已经不用L心那些烦人的for循环的表辑ּ和嵌套了。毕竟,我们大部分时间都不会需要去了解游标的具体位|,我们只需要遍历数l或CollectionQ对?</p> <p>  1.6. 自动装箱/自动拆箱</p> <p>  所谓装,是把值类型用它们相对应的引用cd包v来,使它们可以具有对象的特质Q如我们可以把int型包装成Integercȝ对象Q或者把double包装成DoubleQ等{。所谓拆,是跟装q方向相反Q将Integer及Doubleq样的引用类型的对象重新化ؓ值类型的数据?/p> <p>  在J2SE(TM) 5.0发布之前Q我们只能手工的处理装箱和拆。也怽会问Qؓ什么需要装和拆箱?比方说当我们试图一个值类型的数据dC个Collection中时Q就需要先把它装箱Q因为Collection的add()Ҏ只接受对?而当我们需要在E后这条数据取出来Q而又希望使用它对应的值类型进行操作时Q我们又需要将它拆成值类型的版本。现在,~译器可以帮我们自动地完成这些必要的步骤。下面的代码我提供两个版本的装箱和拆,一个版本用手工的方式Q另一个版本则把这些显而易见的代码交给~译器去完成Q?/p> <p> <strong>   </strong>public static void manualBoxingUnboxing(int i) { <br />  <strong>   </strong>ArrayList<Integer> aList = new ArrayList<Integer>(); <br />  <strong>   </strong>aList.add(0, new Integer(i)); <br />  <strong>   </strong>int a = aList.get(0).intValue(); <br />  <strong>   </strong>System.out.println("The value of i is " + a); <br />  <strong>   </strong>} <br /> <br />  <strong>   </strong>public static void autoBoxingUnboxing(int i) { <br />  <strong>   </strong>ArrayList<Integer> aList = new ArrayList<Integer>(); <br />  <strong>   </strong>aList.add(0, i); <br />  <strong>   </strong>int a = aList.get(0); <br />  <strong>   </strong>System.out.println("The value of i is " + a); <br />  <strong>   </strong>} </p> <p>  看到了吧Q在J2SE(TM) 5.0中,我们不再需要显式的d一个值类型的数据转换成相应的对象Q从而把它作为对象传l其他方法,也不必手工的那个代表一个数值的对象拆箱为相应的值类型数据,只要你提供的信息_让编译器信q些装箱/拆箱后的cd在用时是合法的Q比方讲Q如果在上面的代码中Q如果我们用的不是ArrayList<integer>而是ArrayList或者其他不兼容的版本如ArrayList<java.util.date>Q会有编译错误?/p> <p>  当然Q你需要够重视的是:一斚wQ对于值类型和引用cdQ在<a target="_blank">资源</a>的占用上有相当大的区?另一斚wQ装和拆箱会带来额外的开销。在使用q一方便Ҏ的同时Q请不要忘记了背后隐藏的q些也许会媄响性能的因素?/p> <p>  1.7. cd安全的枚?/p> <p>  在介lJ2SE(TM) 5.0中引入的cd安全枚D的用法之前,我想先简单介l一下这一话题的背景?/p> <p>  我们知道Q在C中,我们可以定义枚Dcd来用别名代替一个集合中的不同元素,通常是用于描q那些可以归Zc,而又具备有限数量的类别或者概念,如月份、颜艌Ӏ扑克牌、太阳系的行星、五大洲、四大洋、季节、学U、四则运符Q等{。它们通常看上Lq个样子Q?/p> <p>  typedef enum {SPRING, SUMMER, AUTUMN, WINTER} season;</p> <p>  实质上,q些别名被处理成int帔RQ比?代表SPRINGQ?代表SUMMERQ以此类推。因些别名最l就是intQ于是你可以对它们进行四则运,q就造成了语意上的不明确?/p> <p>  Java一开始ƈ没有考虑引入枚D的概念,也许是出于保持Java语言z的考虑Q但是用Java的广大开发者对于枚丄需求ƈ没有因ؓJava本n没有提供而消失,于是出现了一些常见的适用于Java的枚举设计模式,如int enum和typesafe enumQ还有不开源的枚DAPI和不开源的内部实现?/p> <p>  我大致说一下int enum模式和typesafe enum模式。所谓int enum模式是模仿C中对enum的实玎ͼ如:</p> <p> <strong>   </strong>public class Season { <br />  <strong>   </strong>public static final int SPRING = 0; <br />  <strong>   </strong>public static final int SUMMER = 1; <br />  <strong>   </strong>public static final int AUTUMN = 2; <br />  <strong>   </strong>public static final int WINTER = 3; <br />  <strong>   </strong>} <br />  <strong>   </strong>q种模式跟C中的枚D没有太多本质上的区别QC枚D的局限它基本上也有。而typesafe enum模式则要昑־健壮得多Q?<br />  <strong>   </strong>public class Season { <br />  <strong>   </strong>private final String name; <br />  <strong>   </strong>private Season(String name) { <br />  <strong>   </strong>this.name = name; <br />  <strong>   </strong>} <br />  <strong>   </strong>public String toString() { <br />  <strong>   </strong>return name; <br />  <strong>   </strong>} <br />  <strong>   </strong>public static final Season SPRING = new Season("spring"); <br />  <strong>   </strong>public static final Season SUMMER = new Season("summer"); <br />  <strong>   </strong>public static final Season AUTUMN = new Season("autumn"); <br />  <strong>   </strong>public static final Season WINTER = new Season("winter"); <br />  <strong>   </strong>} </p> <p>  后一U实现首先通过U有的构造方法阻止了对该cȝl承和显式实例化Q因而我们只可能取得定义好的四种SeasoncdQƈ且提供了方便的toString()Ҏ获取有意义的说明Q而且׃q是一个完全意义上的类Q所以我们可以很方便的加入自qҎ和逻辑来自定义我们的枚丄?/p> <p>  最l,Java军_拥抱枚DQ在J2SE(TM) 5.0中,我们看到了这一变化Q它所采用的设计思\基本上就是上面提到的typesafe enum模式。它的语法很单,用一个实际的例子来说Q要定义一个枚举,我们可以q样写:</p> <p>  public enum Language {CHINESE, ENGLISH, FRENCH, HUNGARIAN}</p> <p>  接下来我们就可以通过Language.ENGLISH来用了。呃…q个例子是不是有点太儿U了Q我们来看一个复杂点的例子。用Java的类型安全枚举,我们可以为所有枚丑օ素定义公用的接口Q然后具体到每个元素本nQ可以针对这些接口实C些特定的行ؓ。这对于那些可以归ؓ一c,又希望能通过l一的接口访问的不同操作Q将会相当方ѝ通常Qؓ了实现类似的功能Q我们需要自己来l护一套承关pL者类似的枚D模式。这里借用Java官方|站上的一个例子:</p> <p> <strong>   </strong>public enum Operation { <br />  <strong>   </strong>PLUS { double eval(double x, double y) { return x + y; } }, <br />  <strong>   </strong>MINUS { double eval(double x, double y) { return x - y; } }, <br />  <strong>   </strong>TIMES { double eval(double x, double y) { return x * y; } }, <br />  <strong>   </strong>DIVIDE { double eval(double x, double y) { return x / y; } }; <br /> <br />  <strong>   </strong>// Do arithmetic op represented by this constant <br />  <strong>   </strong>abstract double eval(double x, double y); <br />  <strong>   </strong>} <br />  <strong>   </strong>在这个枚举中Q我们定义了四个元素Q分别对应加减乘除四则运,对于每一U运,我们都可以调用eval()ҎQ而具体的Ҏ实现各异。我们可以通过下面的代码来试验上面q个枚Dc: <br />  <strong>   </strong>public static void main(String args[]) { <br />  <strong>   </strong>double x = Double.parseDouble(args[0]); <br />  <strong>   </strong>double y = Double.parseDouble(args[1]); <br />  <strong>   </strong>for (Operation op : Operation.values()) { <br />  <strong>   </strong>System.out.println(x + " " + op + " " + y + " = " + op.eval(x, y)); <br />  <strong>   </strong>} <br />  <strong>   </strong>} </p> <p>  怎么P使用枚DQ我们是不是能够很方便的实现一些有的功能?其实说穿了,Java的类型安全枚丑ְ是包含了有限数量的已生成好的自n实例的一U类Q这些现成的实例可以通过cȝ静态字D|获取?/p> <p>  1.8. 可变长度参数</p> <p>  ֐思义Q可变长度参数就是指在方法的参数体中Q只要定义恰当,我们可以使用L数量的参敎ͼcM于用数l。在J2SE(TM) 5.0中,一个新的语法被引入Q就是在参数cd名称后面加上"..."Q表CҎ可以接受多个该类型的参数。需要说明的是可变长度参数必L在参数列表的最后,且一个方法只能包含一个这L参数。在Ҏ体内部,q样的参数被当作数组处理Q看上去代码应该cMq个样子Q?/p> <p> <strong>   </strong>public String testVararg(String... args) { <br />  <strong>   </strong>StringBuilder sb = new StringBuilder(); <br />  <strong>   </strong>for (String str : args) { <br />  <strong>   </strong>sb.append(str); <br />  <strong>   </strong>} <br />  <strong>   </strong>return sb.toString(); <br />  <strong>   </strong>} <br /> </p> <p>  q样的方法签名跟你写成testVararg(String[] args)的区别在于:在调用时Q你不再需要传入一个包装好的String数组Q你只需要简单的写一q串String参数Q以逗号隔开卛_Q就如同q个Ҏ正好有一个重载的版本是接受那么多个String参数一栗?/p> <p>  1.9. 静态引?/p> <p>  所谓静态引入就是指除了引入cM外,我们现在又多了一U选择Q引入某个类的静态字Dc如Q?/p> <p>  import static java.lang.Math.PI;</p> <p>  或?/p> <p>  import static java.lang.Math.*;</p> <p>  q样我们在接下来的代码中Q当我们需要用某个被引入的静态字D|Q就不用再写上前面的cd了。当Ӟ出现名字冲突Ӟ跟原来的cd入一Pq是需要前~以示区分。我个h认ؓq个新语a元素意义不大。当引入太多静态字D后Q代码会变得难以阅读和维护。由于静态字D늚名字通常不如cd那么h描述性,我认为原先在静态字D前写上cd才是更好的选择。不q,毕竟每个人的喜好和需求不同,如果你觉得它对你有用Q既然提供了Q那么就用咯?/p> <p>  1.10. 元数?注解)</p> <p>  注解是J2SE(TM) 5.0引入的重要语a元素Q它所对应的JSR是JSR 175Q我们先来看看JSR 175的文对注解的说明:</p> <p>  注解不会直接影响E序的语义,而开发和部v工具则可以读取这些注解信息,q作相应处理Q如生成额外的Java源代码、XML文档、或者其他将与包含注解的E序一起用的物g?/p> <p>  在之前的J2SE版本中,我们已经使用C一部分早期的注解元素,如@deprecated{。这些元素通常被用于?a target="_blank">HTML</a>的Javadoc。在J2SE(TM) 5.0中,注解被正式引入,且推CJava历史上前所未有的高度?/p> <p>  现在Q注解不仅仅被用来生JavadocQ更重要的,注解使得代码的编译期查更加有效和方便Q同时也增强了代码的描述能力。有一些注解是随着J2SE(TM) 5.0一起发布的Q我们可以直接用。除此之外,我们也可以很方便的实现自定义的注解。在此基上,很多以前我们只能靠反机制来完成的功能也变得更加Ҏ实现?/p> <p>  我们来看现成的有哪些有用的注解:</p> <p>  首先是@OverrideQ这个注解被使用在方法上Q表明这个方法是从其父类l承下来的,q样的写法可以很方便的避免我们在重写l承下来的方法时Q不至于不小心写错了Ҏ{֐Q且悄悄的溜q了~译器,造成隐蔽性相当高的bug?/p> <p>  其次是@DeprecatedQ表明该?cR字Dc方?不再被推荐用?/p> <p>  q有一个@SuppressWarningsQ表明该?cR字Dc方?所늛的范围不需要显C所有的警告信息。这个注解需要提供参敎ͼ如unchecked{等?/p> <p>  下面我通过一个例子向大家说明q些现成的注解的用法Q?/p> <p> <strong>   </strong>public class Main { <br />  <strong>   </strong>@Deprecated <br />  <strong>   </strong>public String str; <br />  <strong>   </strong>public static void main(String[] args) { <br />  <strong>   </strong>new SubMain().doSomething(); <br />  <strong>   </strong>} <br />  <strong>   </strong>public void doSomething() { <br />  <strong>   </strong>System.out.println("Done."); <br />  <strong>   </strong>} <br />  <strong>   </strong>} <br /> <br />  <strong>   </strong>class SubMain extends Main { <br />  <strong>   </strong>@Override <br />  <strong>   </strong>@SuppressWarnings("unchecked", "warning") <br />  <strong>   </strong>public void doSomething() { <br />  <strong>   </strong>java.util.ArrayList aList = new java.util.ArrayList(); <br />  <strong>   </strong>aList.add(new Integer(0)); <br />  <strong>   </strong>System.out.println("Done by SubMain."); <br />  <strong>   </strong>} <br />  <strong>   </strong>} </p> <p>  当然Q我们也完全可以写自q注解。注解定义的语法是@interface关键字。J2SE(TM) 5.0支持三种形式的注解:不带参数的标记注解、带一个参数的注解和带多个参数的完整注解。下面分别D例说明:</p> <p> <strong>   </strong>标记注解Q类似@DeprecatedQ如Q?<br />  <strong>   </strong>@interface SomeEmptyAnnotation {} <br />  <strong>   </strong>单个参数的注解,如: <br />  <strong>   </strong>@interface MySingleElementAnnotation { <br />  <strong>   </strong>String value(); <br />  <strong>   </strong>} <br />  <strong>   </strong>以及多个参数的注解,如: <br />  <strong>   </strong>@interface MyAnnotationForMethods { <br />  <strong>   </strong>int index(); <br />  <strong>   </strong>String info(); <br />  <strong>   </strong>String developer() default "Sean GAO"; <br />  <strong>   </strong>} </p> <p>  我们可以看到Q注解的定义跟interface的定义相当类|我们q可以指定默认倹{对于这些注解,我们也可以ؓ其添加注解,所?#8220;注解的注?#8221;。比方讲Q我们通常会用@Target指定注解的作用对象,以及用@Retention指定注解信息写入的别,如源代码、类文g{等。D个例子:</p> <p> <strong>   </strong>@Target(ElementType.METHOD) <br />  <strong>   </strong>@Retention(RetentionPolicy.SOURCE) <br />  <strong>   </strong>public @interface SignedMethod { <br />  <strong>   </strong>} <br />  <strong>   </strong>在用时Q我们需要在注解名称前面写上@Q然?)中指定参数|如: <br />  <strong>   </strong>@MyAnnotationForMethods ( <br />  <strong>   </strong>index = 1, <br />  <strong>   </strong>info = "This is a method to test MyAnnotation.", <br />  <strong>   </strong>developer = "Somebody else" <br />  <strong>   </strong>) <br />  <strong>   </strong>public void testMethod1() { <br />  <strong>   </strong>// ... <br />  <strong>   </strong>} </p> <p>  注解的最大作用在于它在源代码的基上增加了有用的信息,使得源代码的描述性更强。这些信息可以被代码之外的工兯别,从而可以很方便的增加外部功能,以及减少不必要的相关代码/文g的维护。这里我想简单提一个超出J2SE(TM) 5.0范畴的话题:在未来的EJB 3.0规范中会有相当多的对注解的应用,让我们预览一下将来的无状态会话bean用注解来定义会是什么样子:</p> <p> <strong>   </strong>@Stateless public class BookShelfManagerBean { <br />  <strong>   </strong>public void addBook(Book aBook) { <br />  <strong>   </strong>// business logic goes here... <br />  <strong>   </strong>} <br />  <strong>   </strong>public Collection getAllBooks() { <br />  <strong>   </strong>// business logic goes here... <br />  <strong>   </strong>} <br />  <strong>   </strong>// ... <br />  <strong>   </strong>} </p> <p>  我们甚至不用写Q何接口和部v描述W,q些工作完全由外部工具通过d注解加上反射来完成,q不是很好吗?</p> <p>  1.11. C风格格式化输?/p> <p>  Javaȝ也有cMC的printf()风格的方法了Q方法名同样叫作printf()Q这一Ҏ依赖于前边提到的可变长度参数。D个例子来_我们现在可以写:</p> <p>  System.out.printf("%s has a value of %d.%n", someString, a);</p> <p>  怎么P看上去还不错?需要注意的是JavaZ支持多^収ͼ新增?n标示W,作ؓ对\n的补充。有关Java格式化输出的具体语法Q请参考java.util.Formatter的API文?/p> <p>  1.12. l语</p> <p>  在这一介l性的文章中,我们一起领略了J2SE 5.0带来的新的语a元素Q不知道大家是否也跟W者一P感受Cq些新特性在提高我们的开发效率上所作的巨大努力。其实不只是语言元素QJ2SE(TM) 5.0的发布在其他很多斚w都作了不的改进Q包括虚拟机、新的APIcd{等Q性能和功能上都有大幅提升?/p> <p>  对于主要靠J2EE吃饭的朋友来Ԍ也许真正意义上要在工作中充分利用q些新的元素Q恐怕要{主的J2EE<a target="_blank">服务?/a>都支持J2EE(TM) 5.0的那一天了Q对此我充满期待?br /> </p> <img src ="http://www.tkk7.com/redcoatjk/aggbug/321093.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/redcoatjk/" target="_blank">redcoatjk</a> 2010-05-16 15:35 <a href="http://www.tkk7.com/redcoatjk/archive/2010/05/16/321093.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java中的double相加的怪事http://www.tkk7.com/redcoatjk/archive/2010/03/07/314761.htmlredcoatjkredcoatjkSun, 07 Mar 2010 09:23:00 GMThttp://www.tkk7.com/redcoatjk/archive/2010/03/07/314761.htmlhttp://www.tkk7.com/redcoatjk/comments/314761.htmlhttp://www.tkk7.com/redcoatjk/archive/2010/03/07/314761.html#Feedback0http://www.tkk7.com/redcoatjk/comments/commentRss/314761.htmlhttp://www.tkk7.com/redcoatjk/services/trackbacks/314761.html 标题           在Java中实现QҎ的精计?        AYellowQ原作)   修改          
  关键?          Java   点?  _计算        
   
   
  问题的提出:   
  ~译q行下面q个E序会看C么?  
  public   class   Test{  
          public   static   void   main(String   args[]){  
                  System.out.println(0.05+0.01);  
                  System.out.println(1.0-0.42);  
                  System.out.println(4.015*100);  
                  System.out.println(123.3/100);  
          }  
  };  
   
  你没有看错!l果实? 
  0.060000000000000005  
  0.5800000000000001  
  401.49999999999994  
  1.2329999999999999  
   
  Java中的单QҎcdfloat和double不能够进行运。不光是JavaQ在其它很多~程语言中也有这L问题。在大多数情况下Q计的l果是准的Q但是多试几ơ(可以做一个@环)可以试出类g面的错误。现在终于理解ؓ什么要有BCD码了? 
  q个问题相当严重Q如果你?.999999999999元,你的计算机是不会认ؓ你可以购?0元的商品的? 
  在有的编E语a中提供了专门的货币类型来处理q种情况Q但是Java没有。现在让我们看看如何解决q个问题? 
   
     
   
  四舍五入  
  我们的第一个反应是做四舍五入。MathcM的roundҎ不能讄保留几位数Q我们只能象q样Q保留两位)Q? 
  public   double   round(double   value){  
          return   Math.round(value*100)/100.0;  
  }  
   
  非常不幸Q上面的代码q不能正常工作,l这个方法传?.015它将q回4.01而不?.02Q如我们在上面看到的  
  4.015*100=401.49999999999994  
  因此如果我们要做到精的四舍五入Q不能利用简单类型做Mq算  
  java.text.DecimalFormat也不能解册个问题:  
  System.out.println(new   java.text.DecimalFormat("0.00").format(4.025));  
  输出?.02  
   
     
   
  BigDecimal  
  在《Effective   Java》这本书中也提到q个原则Qfloat和double只能用来做科学计或者是工程计算Q在商业计算中我们要? java.math.BigDecimal。BigDecimal一共有4个够造方法,我们不关心用BigInteger来够造的那两个,那么q有两个Q? 它们是:  
  BigDecimal(double   val)    
                      Translates   a   double   into   a   BigDecimal.    
  BigDecimal(String   val)    
                      Translates   the   String   repre   sentation   of   a   BigDecimal   into   a   BigDecimal.  
   
  上面的API要描q相当的明确Q而且通常情况下,上面的那一个用v来要方便一些。我们可能想都不惛_用上了,会有什么问题呢Q等到出了问题的时候,才发C面哪个够造方法的详细说明中有q么一D:  
  Note:   the   results   of   this   constructor   can   be   somewhat   unpredictable.   One   might   assume   that   new   BigDecimal(.1)   is   exactly   equal   to   .1,   but   it   is   actually   equal   to   .1000000000000000055511151231257827021181583404541015625.   This   is   so   because   .1   cannot   be   represented   exactly   as   a   double   (or,   for   that   matter,   as   a   binary   fraction   of   any   finite   length).   Thus,   the   long   value   that   is   being   passed   in   to   the   constructor   is   not   exactly   equal   to   .1,   appearances   nonwithstanding.    
  The   (String)   constructor,   on   the   other   hand,   is   perfectly   predictable:   new   BigDecimal(".1")   is   exactly   equal   to   .1,   as   one   would   expect.   Therefore,   it   is   generally   recommended   that   the   (String)   constructor   be   used   in   preference   to   this   one.  
   
  原来我们如果需要精计,非要用String来够造BigDecimal不可Q在《Effective   Java》一书中的例子是用String来够造BigDecimal的,但是书上却没有强调这一点,q也许是一个小的p吧? 
     
   
  解决Ҏ  
  现在我们已经可以解决q个问题了,原则是用BigDecimalq且一定要用String来够造? 
  但是惛_一下吧Q如果我们要做一个加法运,需要先两个QҎ转ؓStringQ然后够造成BigDecimalQ在其中一个上调用addҎQ传入另 一个作为参敎ͼ然后把运的l果QBigDecimalQ再转换为QҎ。你能够忍受q么烦琐的过E吗Q下面我们提供一个工LArith来简化操作。它 提供以下静态方法,包括加减乘除和四舍五入:  
  public   static   double   add(double   v1,double   v2)  
  public   static   double   sub(double   v1,double   v2)  
  public   static   double   mul(double   v1,double   v2)  
  public   static   double   div(double   v1,double   v2)  
  public   static   double   div(double   v1,double   v2,int   scale)  
  public   static   double   round(double   v,int   scale)  
   
   
   
  附录  
   
   
  源文件Arith.javaQ? 
   
  import   java.math.BigDecimal;  
  /**  
    *   ׃Java的简单类型不能够_的对点数进行运,q个工具cL供精  
    *   的点数运,包括加减乘除和四舍五入? 
    */  
   
  public   class   Arith{  
   
          //默认除法q算_ֺ  
          private   static   final   int   DEF_DIV_SCALE   =   10;  
   
   
          //q个cM能实例化  
          private   Arith(){  
          }  
   
     
          /**  
            *   提供_的加法运? 
            *   @param   v1   被加? 
            *   @param   v2   加数  
            *   @return   两个参数的和  
            */  
   
          public   static   double   add(double   v1,double   v2){  
                  BigDecimal   b1   =   new   BigDecimal(Double.toString(v1));  
                  BigDecimal   b2   =   new   BigDecimal(Double.toString(v2));  
                  return   b1.add(b2).doubleValue();  
          }  
   
          /**  
            *   提供_的减法运? 
            *   @param   v1   被减? 
            *   @param   v2   减数  
            *   @return   两个参数的差  
            */  
   
          public   static   double   sub(double   v1,double   v2){  
                  BigDecimal   b1   =   new   BigDecimal(Double.toString(v1));  
                  BigDecimal   b2   =   new   BigDecimal(Double.toString(v2));  
                  return   b1.subtract(b2).doubleValue();  
          }    
   
          /**  
            *   提供_的乘法运? 
            *   @param   v1   被乘? 
            *   @param   v2   乘数  
            *   @return   两个参数的积  
            */  
   
          public   static   double   mul(double   v1,double   v2){  
                  BigDecimal   b1   =   new   BigDecimal(Double.toString(v1));  
                  BigDecimal   b2   =   new   BigDecimal(Double.toString(v2));  
                  return   b1.multiply(b2).doubleValue();  
          }  
   
     
   
          /**  
            *   提供Q相对)_的除法运,当发生除不尽的情冉|Q精到  
            *   数点以?0位,以后的数字四舍五入? 
            *   @param   v1   被除? 
            *   @param   v2   除数  
            *   @return   两个参数的商  
            */  
   
          public   static   double   div(double   v1,double   v2){  
                  return   div(v1,v2,DEF_DIV_SCALE);  
          }  
   
     
   
          /**  
            *   提供Q相对)_的除法运。当发生除不的情况Ӟ由scale参数? 
            *   定精度,以后的数字四舍五入? 
            *   @param   v1   被除? 
            *   @param   v2   除数  
            *   @param   scale   表示表示需要精到数点以后几位? 
            *   @return   两个参数的商  
            */  
   
          public   static   double   div(double   v1,double   v2,int   scale){  
                  if(scale<0){  
                          throw   new   IllegalArgumentException(  
                                  "The   scale   must   be   a   positive   integer   or   zero");  
                  }  
                  BigDecimal   b1   =   new   BigDecimal(Double.toString(v1));  
                  BigDecimal   b2   =   new   BigDecimal(Double.toString(v2));  
                  return   b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();  
          }  
   
     
   
          /**  
            *   提供_的小C四舍五入处理? 
            *   @param   v   需要四舍五入的数字  
            *   @param   scale   数点后保留几位  
            *   @return   四舍五入后的l果  
            */  
   
          public   static   double   round(double   v,int   scale){  
                  if(scale<0){  
                          throw   new   IllegalArgumentException(  
                                  "The   scale   must   be   a   positive   integer   or   zero");  
                  }  
                  BigDecimal   b   =   new   BigDecimal(Double.toString(v));  
                  BigDecimal   one   =   new   BigDecimal("1");  
                  return   b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();  
          }  
  };  




redcoatjk 2010-03-07 17:23 发表评论
]]>
[转]Java接口和Java抽象c?/title><link>http://www.tkk7.com/redcoatjk/archive/2009/05/20/271669.html</link><dc:creator>redcoatjk</dc:creator><author>redcoatjk</author><pubDate>Wed, 20 May 2009 02:41:00 GMT</pubDate><guid>http://www.tkk7.com/redcoatjk/archive/2009/05/20/271669.html</guid><wfw:comment>http://www.tkk7.com/redcoatjk/comments/271669.html</wfw:comment><comments>http://www.tkk7.com/redcoatjk/archive/2009/05/20/271669.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/redcoatjk/comments/commentRss/271669.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/redcoatjk/services/trackbacks/271669.html</trackback:ping><description><![CDATA[     摘要:   Java接口和Java抽象c?    在没有好好地研习面向对象设计的设计模式之前,我对Java接口和Java抽象cȝ认识q是很模p,很不可理解?        刚学Java语言Ӟ很隄解ؓ什么要有接口这个概念,虽说是可以实现所谓的多承,可一个只有方法名Q没有方法体的东西,...  <a href='http://www.tkk7.com/redcoatjk/archive/2009/05/20/271669.html'>阅读全文</a><img src ="http://www.tkk7.com/redcoatjk/aggbug/271669.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/redcoatjk/" target="_blank">redcoatjk</a> 2009-05-20 10:41 <a href="http://www.tkk7.com/redcoatjk/archive/2009/05/20/271669.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://hljjlhl.com" target="_blank">߲޵һĻ</a>| <a href="http://9v9av.com" target="_blank">ëƬ޾Ʒ</a>| <a href="http://zhaosifuwang.com" target="_blank">AVһ</a>| <a href="http://zibochanglong.com" target="_blank">ްv2017</a>| <a href="http://sdsxyz.com" target="_blank">VAۺVAVA</a>| <a href="http://gnebs.com" target="_blank">վ߹ۿ</a>| <a href="http://cdhxfj.com" target="_blank">þ99ۺϾƷҳ</a>| <a href="http://avxyz.com" target="_blank">91վ߹ۿ</a>| <a href="http://dddd20.com" target="_blank">㽶Ƶ߹ۿ</a>| <a href="http://ekyzs.com" target="_blank">88avѹۿ</a>| <a href="http://05942688.com" target="_blank">ҹav2019</a>| <a href="http://hbqueena.com" target="_blank">ëƬƵ</a>| <a href="http://xxx2222.com" target="_blank">ҰƵ߹1</a>| <a href="http://c4665.com" target="_blank">һƷƵ</a>| <a href="http://zzhjnmzp.com" target="_blank">ˬִ̼վ</a>| <a href="http://qzllw.com" target="_blank">޹˳߹ۿ69վ</a>| <a href="http://5shitou.com" target="_blank">18վƬѹۿ</a>| <a href="http://0359jgyy.com" target="_blank">޳˶߹ۿ</a>| <a href="http://js-jiarui.com" target="_blank">ĻӰԺ߲</a>| <a href="http://48eh.com" target="_blank">ؼaƬëƬѿ</a>| <a href="http://hkschooltv.com" target="_blank">뾫Ʒ</a>| <a href="http://bdyls.com" target="_blank">ûɫվ</a>| <a href="http://bjtjchem.com" target="_blank">޾ƷþþþAPP</a>| <a href="http://pjszlw.com" target="_blank">޸רƵ</a>| <a href="http://haodiaose35pao.com" target="_blank">Ļһ</a>| <a href="http://aaaaa123.com" target="_blank">ŷഺɫУ԰С˵</a>| <a href="http://www137av.com" target="_blank">Ʒѿ㽶</a>| <a href="http://8xjr.com" target="_blank">baoyu122.Ƶ</a>| <a href="http://aizaicc.com" target="_blank">޳AVƬþ</a>| <a href="http://baiyifuwu.com" target="_blank">߹ۿëƬ</a>| <a href="http://6t23.com" target="_blank">ѹۿ</a>| <a href="http://yuntao360.com" target="_blank">㽶Ʒþ</a>| <a href="http://cpsc-test.com" target="_blank">97ۺɫ</a>| <a href="http://323799.com" target="_blank">aëƬƵ</a>| <a href="http://527352.com" target="_blank">һëƬѲ</a>| <a href="http://www97544.com" target="_blank">츾þþƷ</a>| <a href="http://by33321.com" target="_blank">avպavŷv</a>| <a href="http://cqtchtwq.com" target="_blank">67194Ʒѹۿ</a>| <a href="http://2255325.com" target="_blank">Ʒާѡ벥Ų </a>| <a href="http://91ttvv.com" target="_blank">һ</a>| <a href="http://www-75044.com" target="_blank">޳aƬ߹ۿapp</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>