文档章节

Java基础方面的陷阱(1)

英年求肥
 英年求肥
发布于 2013/07/13 02:39
字数 856
阅读 69
收藏 2

01. 找奇数 ★★★☆☆


    不能用 i % 2 == 1 来当条件,因为需要考虑负数。
    判断一个数是否为奇数的条件应该是 “不能整除”。
    而不是 除了2之后 等于 1。

public static boolean isOdd(int i){
        return i % 2 != 0; // “不能整除”
}
public static void main(String[] args){
   syso(isOdd(-1)); // true
   syso(isOdd(0)); // false
   syso(isOdd(1)); // true
   syso(isOdd(2)); // false
}


02. 浮点数相减 ★★★★★


public static void main(String[] args){
 System.out.println(2.0 - 1.1); // = 0.89999999  不符合需求,应该是0.9才对
 System.out.printf("%.1f", 2.0 - 1.1); // = 0.9  JDK API特性使然
 BigDecimal value = new BigDecimal("2.0")
                           .subtract(new BigDecimal("1.1"));
 syso(value);
}


03. 长整除 ★★★★★


public static void main(String[] args){
        final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000; // 微秒
        final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000; // 毫秒
        syso(MICROS_PER_DAY / MILLIS_PER_DAY); // = 5 错误 应该是1000
        
        /*
            java语法中 对于乘法两端的常数 24和60 会默认为int类型
            这样一直乘下去 就会出现越界情况
            正确的解决方案应该是:
                强调其为Long类型的数据
        */
        final long MICROS_PER_DAY = 24L * 60 * 60 * 1000 * 1000; // 微秒
        final long MILLIS_PER_DAY = 24L * 60 * 60 * 1000; // 毫秒
        syso(MICROS_PER_DAY / MILLIS_PER_DAY); // = 1000
    }


04. 互换内容 ★★☆☆☆


public static void main(String[] args){
        // 不需要定义temp变量 实现数值互换
        int x = 5;
        int y = 8;
        
        x = x ^ y; // 第一次 x = 13 ,y = 8 不变
        y = x ^ y; // 第二次 x = 13 , y = 5, 原理为 一个数异或同一个数两次 结果还是原来的值
        x = x ^ y; // 第三次 x = 8, y = 5 依旧为5
        syso("x = " + x + ", y = " + y); // x=0, y=1984
    }


05. 字符串和字符 ★★★★★


public static void main(String[] args){
        syso("H" + "a"); // Ha
        syso('H' + 'a'); // 169
        /*
            由于char类型的数据在加减乘除运算中,
            会自动提升为int类型的数据。
            使用ascii表来存储char类型数据具体的值。
            所以就会变成
            'H' = 72
            'a' = 97
            所以等于 169
        */
    }


06. 字符数组 ★★★★☆


public static void main(String[] args){    
        String letters = "ABC";
        char[] numbers = {'1','2','3'};
        System.out.println(letters + "easy as " + numbers);  // ABC easy as [C@de6ced
        System.out.println(numbers); // 123
        /*
            println()该方法为重构,可以传递String类型参数,
            也可传递其它类型参数。
            当与字符串拼接的时候,println()方法默认传递的参数为字符串类型。
            那么,数组会调用自身的toString()方法,即打印该数组的哈希码
            如果println()中传递的参数为char[]数组,
            默认将一个字节数组中的所有数,一一打印出来,便成了 123.
        */
        
    }


07. 转义字符 ★★☆☆☆


public static void main(String[] args){    
        // \u0022 是双引号的Unicode转义字符
        System.out.println("a\u0022.length()+\u0022b".length());// = 2
        // 说白了 就是 "a".length() + "b".length() = 2
    }


08. 打印输出类名 ★★☆☆☆


public static void main(String[] args){    
        
        System.out.println(
            MyClass.class.getName()
                .replaceAll(".","/") + ".class"
        );
        // 特殊字符必须转义 不然输出结果会事与愿违u
        System.out.println(
            MyClass.class.getName()
                .replaceAll("\\.","/") + ".class"
        );
        
    }


09. 随机数问题 ★★★★☆


public class RandomTest{
        private static Random rnd = new Random();
        public static void main(String[] args){    
            StringBuffer word = null;
            switch(rnd.nextInt(2)){
                case 1: word = new StringBuffer('P');
                    break;
                case 2: word = new StringBuffer('G');
                    break;
                default: word = new StringBuffer('M');
            }
            word.append('a');
            word.append('i');
            word.append('n');
            System.out.println(word); // 输出结果为: ain
            /*
                该题有3个知识点
                1. case语句后面一定要加上break。
                2. char类型的数据会自动提升为int类型,所以需要加上双引号,
                    将其改为字符串数据类型。
                3. rnd.nextInt(2) 得出的结果是 0到2 不包含2
                    也就是只有 0 1
                    所以就算都改正了,但是Gain也一定不会出现的,因为条件不允许。
                switch(rnd.nextInt(2)){
                case 1: word = new StringBuffer("P");
                    break;
                case 2: word = new StringBuffer("G");
                    break;
                default: word = new StringBuffer("M");
            }
            */
        
        }
    }

本文转载自:

共有 人打赏支持
英年求肥
粉丝 1
博文 12
码字总数 8366
作品 0
广州
程序员
Java自动装箱与拆箱及其陷阱

在本文中,笔者向大家介绍下Java中一个非常重要也非常有趣的特性,就是自动装箱与拆箱,并从源码中解读自动装箱与拆箱的原理,同时这种特性也留有一个陷阱。开发者如果不注意,就会很容易跌入...

LCZ777
2014/07/26
0
0
Java学习---Java简单认识

前言 小编在学习Java方面的基础知识,发现里面有很多是结合之前的语言的特点发展过来的,不同的地方是,Java有它自己的发展和特点。下面小编先简单地做一下总结,结合看过的1-2章的J2SE视频,...

m18633778874
04/01
0
0
Java__线程---基础知识全面实战---坦克大战系列为例

今天想将自己去年自己编写的坦克大战的代码与大家分享一下,主要面向学习过java但对java运用并不是很熟悉的同学,该编程代码基本上涉及了java基础知识的各个方面,大家可以通过练习该程序对自...

x-knight_勋爵
2016/04/02
0
0
JAVA基础再回首(三十)——JAVA基础再回首完美结束,感概万千!

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m366917/article/details/52724939 JAVA基础再回首(三十)——JAVA基础再回首完美结束,感概万千! 经过了几...

Aduroidpc
2016/10/02
0
0
亮剑JVM的9款编程语言杀手开发利器重磅推荐

随着各种各样的编程语言铺地盖地向我们涌来,软件世界似乎变得有点疯狂了。JVM的帝国在不断地壮大,它已经不满足于只作为Java语言的运行平台。它勇敢地将自己的触角伸向了JRuby,Groovy等等,...

ndjys
2012/03/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

你为什么在Redis里读到了本应过期的数据

一个事故的故事 晚上睡的正香突然被电话吵醒,对面是开发焦急的声音:我们的程序在访问redis的时候读到了本应过期的key导致整个业务逻辑出了问题,需要马上解决。 看到这里你可能会想:这是不...

IT--小哥
今天
2
0
祝大家节日快乐,阖家幸福! centos GnuTLS 漏洞

yum update -y gnutls 修复了GnuTLS 漏洞。更新到最新 gnutls.x86_64 0:2.12.23-22.el6 版本

yizhichao
昨天
5
0
Scrapy 1.5.0之选择器

构造选择器 Scrapy选择器是通过文本(Text)或 TextResponse 对象构造的 Selector 类的实例。 它根据输入类型自动选择最佳的解析规则(XML vs HTML): >>> from scrapy.selector import Sele...

Eappo_Geng
昨天
4
0
Windows下Git多账号配置,同一电脑多个ssh-key的管理

Windows下Git多账号配置,同一电脑多个ssh-key的管理   这一篇文章是对上一篇文章《Git-TortoiseGit完整配置流程》的拓展,所以需要对上一篇文章有所了解,当然直接往下看也可以,其中也有...

morpheusWB
昨天
5
0
中秋快乐!!!

HiBlock
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部