zoukankan      html  css  js  c++  java
  • 《Java核心技术》学习笔记 第1-3章

    第一章  Java程序设计概述

      在网页中运行的Java程序称为 applet.

      在服务器中运行的Java程序称为 servlet.

    关于Java的常见误解:

    其中第三点说到: 3.Java是一种非常容易学习的程序设计语言

    像Java这种功能强大的语言大都不太容易学习. 首先,必须将编写玩具式程序的轻松和开发实际项目的艰难区分开来.

    第二章  Java程序设计环境

    Windows 或 Linux : 32位选择x86, 64位以 x64

     

    第三章  Java的基本程序设计结构

    3.1 一个简单的Java应用程序

    根据Java语言规范, main方法必须声明为pulic, 不过, 当main方法不是public时, 有些版本的Java解释器也可以执行Java程序.

    在Java SE 1.4 及以后的版本中,强制main方法时public的.  

    3.2 注释

    在Java中,有三种标记注释的方式。最常用的方式是使用 // ,其注释内容从 // 开始到本行结束

    System.out.println(" We will not use 'Hello World!'"); // is this too cute?

    当需要长篇的注释时时,既可以在每行注释前标记//,也可以使用/* 和 */ 将一段比较长的注释括起来。

    第三种注释可以用来自动生成文档,这种文档以/** 开始,以*/ 结束。

        /**
         * This is the first sample program in Core Java Chapter 3
         * @param args
         */
        public static void main(String[] args) {
            System.out.println(" We will not use 'Hello World!'"); // is this too cute?
        }

    在Java中, /* */ 注释不能嵌套。也就是说,不能简单地把代码用/* 和 */括起来作为注释,因为这段代码本身可能也含一个 */ 。

    3.3 数据类型

    Java是一种强类型语言. 这就意味着必须为每一个变量声明一种类型.

    在Java中,一共有8种基本类型(primitive type)

    3.3.1 整型

    其中有4种整型、2种浮点类型、1种用于表示Unicode编码的字符单元的字符类型  char 和 1 种用于表示真值的boolean 类型。

    类型  存储需求 取值范围

    int

    4字节 -2 147 483 648 ~ 2 147 483 647 (正好超过21亿)

    short

    2字节 -32 768 ~ 32767

    long

    8字节 -9 223 372 036 854 775 808 ~ 9 223 372 036 854 775 807

    byte

    1字节 -128 ~ 127

     

    在通常情况下,int类型最常用。但如果表示星球上的居住人数,就需要使用long类型了。byte 和 short 类型主要用于特定的应用场合,例如,底层的文件处理或者需要控制占用空间量的大数组。

    3.3.2 浮点类型

    浮点类型用于表示有小数部分的数值。在Java中有两种浮点类型

    类型  存储需求 取值范围
    float 4字节 大约 +- 3.402 823 47E+38F(有效位数为6~7位)
    double 8字节 大约 +-  1.797 693 134 862 315 72E+308(有效位数为15位)

    可以使用十六进制表示浮点数值。例如,0.125=2-3 可以表示成0x1.0p-3

    在十六进制表示法中,使用p表示指数,而不是e。注意,尾数采用十六进制,指数采用十进制。指数的基数是2,而不是10。

    用于表示溢出或出错情况的三个特殊的浮点数值:

    • 正无穷大
    • 负无穷大
    • NaN(不是一个数字)

    例如:一个正整数除以0的结果为正无穷大。计算0/0或者负数的平方根结果为NaN。

    特别要说明的是,不能这样检测一个特定值是否等于Double.NaN:

            double x = 0.2;
            if (x == Double.NaN){  // is never true
                System.out.println("x == Double.NaN");
            }

      所有“非数值”的值都认为i是不相同的。然鹅,可以使用Double.isNaN方法:

            if (Double.isNaN(x))// check whether x is "not a number"    

      浮点数不适用于无法接受舍入误差的金融计算中。例如:

            System.out.println(2.0-1.1);    // 输出结果为:0.8999999999999999

    而不是凡人们想象的 0.9 。

    这种舍入误差的主要原因是浮点数值采用二进制系统表示,而在二进制系统中无法精确地表示分数1/10 。

    这就好像十进制无法精确地表示分数1/3 一样。

    如果在数值计算中不允许有任何舍入误差,就应该使用BigDecimal类。

    3.3.3 char类型

    char类型的字面量值要用单引号括起来。例如'A' 是编码值为65所对应的字符常量。它与"A" 不同,"A"是包含一个字符A的字符串。char类型的值可以表示为十六进制,其范围从 u0000 到 Uffff 。例如:

    u2122 表示注册符号(™),u03C0 表示希腊字母π。

    3.3.4 Unicode与char类型

    3.3.5 boolean类型

    boolean(布尔)类型有两个值:false和true,用来判断逻辑条件。整型值和布尔值之间不能进行相互转换。

    3.4 变量

    3.4.1 变量初始化

    3.4.2 常量

    在Java中,可以使用关键字static final 设置一个常量类。需要注意的是,常量类定义位于main方法地外部。

    3.5 运算符

    需要注意:整数被0除将会产生一个异常,而浮点数被0除将会得到无穷大或NaN结果。

    3.5.1 数学函数与常量

    在Java中,没有幂运算,需要借助Math类得pow方法。语句:

            double x = 2;
            double a = 3;
            double y = Math.pow(x,a);
            System.out.println(y);    // 输出 8.0

     3.5.2 数值类型之间的转换

    上图中6个实心箭头,表示无信息丢失的转换;有3个虚箭头,表示可能有精度损失地转换。例如:123456789 是一个大整数,它所包含的位数比float类型所能够表达的位数大,当将这个整数数值转换为float类型时,将会得到同样大小的结果,但却失去了一定的精度。

            int n = 123456789;
            float f = n;    // f is 1.23456792E8

    当使用上面的两个数值进行二元操作时,先将两个操作数转换为同一种类型,然后再进行计算。

    • 如果两个操作数中有一个是double类型,另一个操作数就会转换为double类型。
    • 否则,如果其中一个操作数是float类型,另一个操作数将会转换成float类型。
    • 否则,如果其中一个操作数是long类型,另一个操作数将会转换成long类型。
    • 否则,两个操作数都将被转换为int类型。

    3.5.3 强制类型转换

    在上一小节中看到,在必要的时候,int 类型地值将会自动地转换为double类型。但另一方面,有时也需要将double转换成int。在Java中,允许进行这种数值之间的类型转换。当然,有可能会丢失一些信息。在这种情况下,需要通过强制类型转换(cast)实现这个操作。强制类型转换地格式是在圆括号中给出想要转换地目标类型,后面紧跟待转换地变量名。例如:

            double x = 9.997;
            int nx = (int) x;   // nx is 9

    这样,变量nx的值为9。强制类型转换通过截断小数部分将浮点型转换为整型。

    如果想对浮点数进行摄入运算,以便的到最接近的整数,那就需要使用Math.round()方法:

            double x = 9.997;
            int nx = (int) Math.round(x);   // nx is 10

    现在,变量nx的值为10。当调用round的时候,仍然需要强制类型转换(int)。其原因是round方法返回的结果是long类型,由于存在信息丢失的可能性,所以只有使用显式的强制类型转换才能够将long类型转换成int 类型。

    3.5.4 结合赋值和运算符

    可以在赋值中使用二元运算符,这是种很简便的方式。例如:

      x += 4; 

    等价于:

      x = x + 4; 

    (一般的,要把运算符放在=号左边,如*=或%=)。

    注释:如果运算符得到一个值,其类型与左侧操作数的类型不同,就会发生强制类型转换。例如,如果 x 是一个int,则以下语句:

      x += 3.5; 

    是合法的,将把x 设置为(int)(x + 3.5)。

     3.5.5 自增与自减运算符

    由于自增,自减运算符会改变变量的值,所以他们的操作数不能是数值。例如, 4++; 就不是一个合法的语句。

    运算符放在操作数后面是“后缀”形式,如: n++; 

    运算符放在操作数前面是“前缀”形式,如: ++n; 

    前缀形式会先完成加1,而后缀形式会使用变量原来的值。

            int m = 7;
            int n = 7;
            int a = 2 * ++m;
            int b = 2 * n++;
            System.out.println("a now is :" + a +",and m now is "+m);   // a now is :16,and m now is 8
            System.out.println("b now is :" + b +",and n now is "+n);   // b now is :14,and n now is 8

    建议不要在表达式中使用++,因为这样的代码很容易让人困惑,而且会带来烦人的bug。

    3.5.6 关系和boolean运算符

    Java支持三元操作符?: ,这个操作符又是很有用。如果条件为true,下面的表达式

     condition ? expression1 : expression2 

    就为第一个表达式的值,否则计算为第二个表达式的值。例如:

     

            int x = 3;
            int y = 4;
            int nx = x < y ? x : y;
            System.out.println(nx);

    会返回x 和 y 中较小的一个。

    3.5.7 位运算符

    处理整型类型时,可以直接对组成整型数值的各个位完成操作。这意味着可以使用掩码技术得到整数中的各个位。位运算符包括:

    &("and")  | ("or")   ^ ("xor")   ~ ("not")

    这些运算符按位模式处理。例如,如果n是一个整数变量,而且用二进制表示的n 从右边数第4位为1,则:

            int n = 8;
            int fourthBitFromRight = (n & 0b1000) / 0b1000;
            System.out.println(fourthBitFromRight);     // 1 因为十进制 8 用二进制表示为 1000
            int m = 4;
            fourthBitFromRight = (m & 0b1000) / 0b1000; // 0 因为十进制 4 用二进制表示为 0100
            System.out.println(fourthBitFromRight);

     会返回1,否则返回0。利用& 并结合使用适当的 2 的幂,可以把其他位掩掉,而只保留其中一位。

     注释:应用在布尔值上,& 和 | 运算符也会得到布尔值。这些运算符与 && 和 || 运算符很类似,不过 & 和 | 运算符不采用“短路”方式求值,也就是说,得到计算结果之前两个操作数都需要计算。

      另外,还有 >> 和 << 运算符将位模式左移或右移。需要建立位模式来完成位掩码,这两个运算符很方便:

            int n = 4;
            int fourBitFromRight = (n & (1 << 3)) >> 3;
            System.out.println(fourBitFromRight);  // 0

    最后,>>> 运算符会用0 填充高位,这与 >> 不同,它会用符号位填充高位。不存在 <<< 运算符。

    警告:位移运算符的有操作要完成模32的运算,(除非左操作数是long类型,在这种情况下需要对右操作数模64)。例如,1<<35 的值等同于 1 << 3或8。

    3.5.8 括号与运算符级别

    同一级别的运算符按照从左到右的次序依次计算(除了表中给出的右结合运算符外)。例如:由于&&的优先级比||的优先级高,所以表达式

     a && b || c ; 

    等价于

     (a && b)|| c ; 

    又因为 += 是右结合运算符,所以表达式

     a += b += c; 

    等价于

     a += (b += c) ; 

    也就是将 b += c的结果(加上c之后的b)加到 a 上。

    运算符 结合性
    [].() (方法调用) 从左至右
    ! ~ ++ -- +(一元运算) - (一元运算) () (强制类型转换) new 从右至左
    * / % 从左至右
    + -  从左至右
    << >> >>> 从左至右
    < <= > >= instanceof 从左至右
    ==  != 从左至右
    & 从左至右
    ^ 从左至右
    | 从左至右
    && 从左至右
    || 从左至右
    ?: 从右至左
    = += -= *= /= %= &= |= ^= <<= >>= >>>= 从右至左

     

    3.5.9 枚举类型

    3.6 字符串

    从概念上讲,Java字符串就是Unicode字符串序列。例如,串“Javau2122” 由5个Unicode字符 J、a、v、a、和™。Java没有内置的字符串类型,而是在标准Java类库中提供了一个预定义类,很自然地叫做String。

    3.6.1 子串

    String类的substring方法可以从一个较大的字符串提取出一个字串。

            String greeting = "Hello";
            String s = greeting.substring(0,3);     // Hel

    substring方法的第二个参数是不想复制的第一个位置。这里要复制位置为0、1、2(从0到2,包括0和2)的字符。在substring中从0开始计数,直到3为止,但不包含3。

    substring的工作方式有一个优点:容易计算子串的长度。字符串s.substring(a,b)的长度为b-a。例如,子串“Hel”的长度为3-0=3。

    3.6.2 拼接

    如果需要把多个字符串放在一起,用一个定界符分隔,可以使用静态join方法:

            String all = String.join(" / ","S","M","L","XL");
            System.out.println("all is the string : ""+all+""");
         // all is the string : "S / M / L / XL"

    3.6.3 不可变字符串

    String类没有提供用于修改字符串的方法。如果希望将greeting的内容改为"Help!",不能直接将greeting的最后两个位置的字符串修改为‘p’和‘!’。在Java中实现这项操作非常容易。首先提取需要的字符,然后在拼接上替换的字符串:

            String greeting = "Hello";
            greeting = greeting.substring(0,3) + "p!";
            System.out.println("greeting is changed to "" + greeting +""");   // greeting is changed to "Help!"

    由于不能修改Java字符串中的字符,所以在Java文档中将String类对象称为不可变字符串,如同数字3永远是数字3一样,字符串“Hello”永远包含字符H、e、l、l 和 o 的代码单元序列,而不能修改其中的任何一个字符。当然,可以修改字符串变量greeting,让它引用另外一个字符串,这就如同可以将存放3的数值变量改成存放4一样。

    不可变字符串却有一个优点:编译器可以让字符串共享。

    3.6.4 检查字符串是否相等

    可以使用equals方法检测两个字符串是否相等。对于表达式:

     s.equals(t) 

    如果字符串s与字符串t相等则返回true;否则返回false。需要注意,s与t 可以是字符串变量,也可以是字符串字面量。例如,下面的表达式是合法的:

     "Hello".equals(greeting); 

    要想检测两个字符串是否相等,而不区分大小写,可以使用equalsIgnoreCase方法。

     "Hello".equalsIgnoreCase(greeting); 

     一定不要使用==运算符检测两个字符串是否相等!这个运算符只能够确定两个字符串是否放置的在同一个位置上。当然,如果字符串放置在同一个位置上,他们必然相等。但是完全有可能将内容相同的多个字符串的拷贝放置在不同的位置上。

            String greeting = "Hello"; // initailize greeting to a string
            if (greeting == "Hello"){
                System.out.println("greeting == "Hello"");    // greeting == "Hello"
            }else {
                System.out.println("greeting != "Hello"");
            }
            if (greeting.substring(0,3) == "Hel"){
                System.out.println("greeting.substring(0,3) == "Hello"");
            }else {
                System.out.println("greeting.substring(0,3) != "Hello"");     // greeting.substring(0,3) != "Hello"
            }

     如果虚拟机始终将相同的字符串共享,就可以使用==运算符检测是否相等。但实际上只有字符串常量是共享的,而+或substring等操作产生的结果并不是共享的。因此,千万不要使用==运算符测试字符串的相等性,以免在程序中出现糟糕的bug。

    3.6.5 空串与Null串

    空串""是长度为0的字符串,可以调用以下代码检查一个字符串是否为空:

            String str = "";
            if (str.length() == 0 && str.equals("")){
                System.out.println("str is """);
            }

      当然   str.length() == 0 或 str.equals("") 都可以检验一个字符串是否为空。

    空串是一个Java对象,有自己的串长度(0)和内容(空)。不过,String变量还可以存放一个特殊的值,名为null,这表示目前没有任何对象与该变量关联。

    有时要检查一个字符串既不是null也不为空串,这种情况下要使用以下条件,注意检查的先后顺序:

     if (str != null && str.length() != 0) 

     

    3.66 码点与代码单元

    Java字符串由char值序列组成。char数据类型是一个采用UTF-16编码表示的Unicode码点的代码单元。大多数常用Unicode字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。

    length方法将返回采用UTF-16编码表示的给定字符串所需要的代码单元数量例如:

            String greeting = "Hello";
            int n = greeting.length();  // n is 5

     要想得到实际的长度,即码点数量,可以调用:

            String greeting = "Hello";
            int cpCount = greeting.codePointCount(0, greeting.length());
            System.out.println("cpCount is "+ cpCount);     // cpCount is 5

     调用s.charAt(n)将返回位置n的代码单元, n 介于0 ~ s.length()-1 之间。

    3.7.2 printf

    3.7.3 文件输入与输出

    文件读取:

     Scanner in = new Scanner(Paths.get("myfile.txt"),"UTF-8"); 

    文件写入:

     PrintWriter out = new PrintWriter("myfile.txt", "UTF-8"); 

    可以用下面的调用方式找到路径的位置:

     System.getProperty("user.dir") 

    3.8.3 循环

    程序清单3-3  Retirement/Retirement.Java

    while(){}

    public class Retirement {
        public static void main(String[] args) {
            // read inputs
            Scanner in = new Scanner(System.in);
    
            System.out.print("How much money do you need to retire? ");
            double goal = in.nextDouble();
    
            System.out.print("How much money will you contribute every year? ");
            double payment = in.nextDouble();
    
            System.out.print("Interest rate in %: ");
            double interestRate = in.nextDouble();
    
            double balance = 0;
            int years = 0;
    
            // update account balance while goal isn't reached
            while (balance < goal)
            {
                // add this year's payment and interest
                balance += payment;
                double interest = balance * interestRate / 100;
                balance += interest;
                years++;
            }
            System.out.println("You can retire in " + years + " years");
        }
    }

     

    do{......}while(boolean)

    public class Retirement2 {
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
    
            System.out.print("How much money will you contribute every year? ");
            double payment = in.nextDouble();
    
            System.out.print("Interest rate is %: ");
            double interestRate = in.nextDouble();
    
            double balance = 0;
            int year = 0;
    
            String input;
    
            // update account balance while user isn't ready to retire
            do {
                // add this year's payment and interest
                balance += payment;
                double interest = balance * interestRate / 100;
                balance += interest;
    
                year++;
    
                // print current balance
                System.out.printf("After year %d, your balance is %,.2f%n", year, balance);
    
                // ask if ready to retire and get input
                System.out.println("Reday to retire? (Y/N) ");
                input = in.next();
            }
            while (input.equals("N"));
        }
    }

     

    3.8.4 确定循环

    do/while

    for

    for语句是while循环的一种简化形式。

            for (int i = 10; i > 0; i--){
                System.out.println("Counting down for... " + i);
            }
         

         // 可重写为:
    int i = 10; while (i > 0){ System.out.println("Counting down while ... " + i); i--; }

     

    程序清单3-5 LotteryOdds/LotteryOdds.java

    public class LotteryOdds {
    
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
    
            System.out.println("How many numbers do you need to draw? ");
            int k = in.nextInt();
    
            System.out.println("What is the highest number you can draw? ");
            int n = in.nextInt();
    
            /**
             * compute binomial coefficient n*(n-1)*(n-2)*...*(n-k+1)/(1*2*3*...*k)
             */
            int lotterOdds = 1;
            for (int i = 1; i <= k; i++){
                lotterOdds = lotterOdds * (n - i + 1) / i;
            }
            System.out.println("Your odds are 1 in " + lotterOdds + ". Good luck!");
        }
    }

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    SignalR
    convert NameValueCollection/Dictionary<string, object> to JSON string
    CG标准函数库
    Unity shader学习之Alpha Blend
    Unity shader学习之Alpha Test
    Unity shader学习之遮罩纹理
    Unity shader学习之渐变纹理
    Unity shader学习之切线空间下计算凹凸映射
    Unity shader学习之Blinn-Phong光照模型
    Unity shader学习之高光反射光照模型
  • 原文地址:https://www.cnblogs.com/Night-Watch/p/11816913.html
Copyright © 2011-2022 走看看