[Java核心技术]学习笔记--第三章
来源:互联网 发布:济南软件外包服务 编辑:程序博客网 时间:2024/06/01 18:12
第三章
Java的基本语法(数据类型、分支以及循环)。
3.1一个简单的Java应用程序
经典的HelloWorld:
public class FirstSample {static public void main(String[] args){System.out.println("We will not use 'Hello world!");}}
编写Java程序的注意事项:
- Java语言对大小写敏感。
- 类名:以大写字母开头的名词。如果类名由多个单词组成,每个单词的第一个字母都应该大写(骆驼命名法:CamelCase)。
- 源代码文件名必须与公共类的名字相同,并用.java作为扩展名。
- 如果源文件没有错误,编译后会生成一个与源文件同名的以.class为扩展名的文件。
- 使用Java ClassName的方式运行。
- 运行时,Java虚拟机将从指定类中的main方法开始执行。
3.2注释
与大多数程序设计语言一样,Java中的注释也不会出现在可执行程序中。因此可以在源代码中添加任意多的注释,不用担心代码膨胀。
Java的三种注释:
- 单行注释"// ", 其注释内容是从//开始到本行结尾。
- 多行注释"/×", "×/"。
- 可用来自动生成文档的注释。以"/××"开始,以"×/"结束。
※需要注意的是,Java中/**/注释不能嵌套。如果代码本身包含了一个×/,就不能用/××/将注释括起来。
3.3数据类型
char类型
用于表示单个字符。通常用来表示字符常量。
boolean类型
有两个值:false和true,用来判断逻辑条件。整型值和布尔值之间不能进行相互转换。
3.4变量
变量名:以字母开头的由字母和数字构成的序列。字母包括'A'~'Z', 'a'~'z', '_', '$'或在某种语言中代表字母的任何Unicode字符。同样,数字包括‘0’~‘9’和在某种语言中代表数字的任何Unicode字符。但是其他符号和空格不能出现在变量名中。
※尽管$是一个合法的Java字符,单不要在你自己的代码中使用这个字符。它只用于Java编译器或其他工具生成的名字中。
3.4.1变量初始化
变量声明后,必须用赋值语句对变量进行显式初始化。
3.4.2常量
在Java中,利用关键字final指示常量。
关键字final表示这个变量只能被赋值一次。一旦被赋值之后,就不能够再更改了。习惯上,常量名使用全大写。
在Java中,经常希望某个常量可以在一个类中的多个方法使用,通常将这些常量成为类常量。
※const是Java保留的关键字,但目前并没有使用。在Java中,必须使用final定义常量。
3.5运算符
位运算:
对以为运算符右侧的参数需要进行模32(求余运算)的运算(除非左边的操作数时long类型,在这种情况下需对右侧操作数模64)。例如,1<<35与1<<3是相同的。
数学函数与常量:
在Math类中,包含了各种各样的数学函数。
计算平方根:
double x = 4;double y = Math.sqrt(x);System.out.println(y);
计算x的a次幂:
double y = Math.pow(x, a);
常用的三角函数:
Math.sin
Math.cos
Math.tan
Math.atan
Math.atan2
指数函数及它们的反函数
Math.exp
Math.log
Math.log10
π和e常量的近似值:
Math.PI
Math.E
3.6字符串
Java没有内置的字符串类型,而是在标准Java类库中提供了一个预定义类String。每个用双引号括起来的字符串都是String类的一个实例。
3.6.1子串
String类的substring方法可以从一个较大的字符串提取出一个子串。
String greeting = "Hello";String s = greeting.substring(0, 3);
上述语句创建了一个由字符“Hel”组成的字符串。
substring的第二个参数时不想复制的第一个位置。substring的工作方式有一个优点:容易计算子串的长度。字符串s.substring(a, b)的长度为b-a。
3.6.2拼接
与绝大多数程序设计语言hi杨,Java允许使用+号连接(拼接)两个字符串。
String expletive = "Expletive";String PG13 = "deleted";String message = expletive + PG13;上述代码讲“Expletivedeleted”赋给变量message。
当将一个字符串与一个非字符串的值进行拼接时,后者被转换成字符串。
3.6.3不可变字符串
String类没有提供用于修改字符串的方法。如果想要修改字符串,首先提取需要的字符,然后在拼接上替换的字符串:
greeting = greeting.subsring(0, 3) + "p!";由于不能修改Java字符串中的字符,因此在Java文档中讲String类对象成为不可变字符串。
可变字符串的优点:编译器可以让字符串共享。
字符串共享的工作方式:可以想象将各种字符串存放在公共的存储池中。字符串变量指向存储池中相应的位置。如果复制一个字符串变量,原始字符串与复制的字符串共享相同的字符。
※Java字符串不是字符型数组,它更像C/C++中的char×指针。
3.6.4检测字符串是否相等
使用equals方法检测字符串相等。
对于s.equals(t),如果s与t相等,则返回true;否则,返回false。
※s和t都可以是字符串变量或字符串常量。例如,下列表达式是合法的:
"Hello".equals(greeting);如果不区分大小写,可以使用equalsIgnoreCase方法。
"Hello".equalsIgnoreCase(greeting);一定不能使用==运算符检测两个字符串是否相等!这个运算符只能够确定两个字符串是否放在同一个位置上。
3.6.5空串与Null串
空串""是长度为0的字符串。可以用如下方式检测字符串是否为空:
if (str.length() == 0)或
if (str.equals(""))空串是一个Java对象,有自己的长度(0)和内容(空)。
String变量还可以存放一个特殊的值,名为Null,着表示目前没有任何对象与该变量关联。检车字符串是否为Null,可以使用如下方法:
if (str == NULL)
有时要检查一个字符串既不是Null又不是空,可是使用以下方法:
if (str != NULL && str.length() != 0)
3.6.6代码点与代码单元
Java字符串由char序列组成。char数据类型是一个采用UTF-16编码表示Unicode代码点的代码单元。大多数的常用Unicode字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。
length方法将返回采用UTF-16编码表示的给定字符串所需要的代码单元数量。
String greeting = "Hello";int n = greeting.length(); // is 5想要得到实际的长度,即代码点数量,可以调用:
int cpCount = greeting.codePointCount(0, greeting.length());调用s.charAt(n)将返回位置n的代码单元,n介于0~s.lenght() - 1之间。
char first = greeting.charAt(0); // first is 'H'\char last = greeting.charAt(4); // las is 'o'
想要得到第i个代码点,应该使用下列语句
int index = greeting.offsetByCodePoint(0, i);int cp = greeting.codePointAt(index);
3.6.7字符串API
String类包含了50多个方法,都很有用。
int indexOf( String str, int fromIndex )
int indexOf( int cp )
int indexOf( int cp, int from Index)返回与字符串str或代码点cp匹配的第一个子串的开始位置。这个位置从索引0或fromIndex开始计算。如果在原始串中不存在str, 返回-1。int lastIndexOf( String str )
int lastIndexOf( String str, int fromIndex )
int lastIndexOf( int cp )
int lastIndexOf( int cp, int from Index)返回与字符串str或代码点cp匹配的最后一个子串的开始位置。这个位置从索引0或fromIndex开始计算。如果在原始串中不存在str, 返回-1。int length()返回字符串的长度。int codePointCount( int startIndex, int endIndex )返回startIndex和endIndex-1之间的代码点数量。没有匹配成对的代用字符将计入代码点。String replace(CharSequence oldString, CharSequence newString)返回一个新字符串。这个字符串用newString代替原始字符串中所有的oldString。可以使用String或StringBuilder对象作为CharSequence参数。boolean startsWith(String prefix)如果字符串以prefix开始,返回true。String substring( int beginIndex )
String substring( int beginIndex, int endIndex )返回一个新字符串。这个字符串包含原始字符串中从beginIndex到串尾或endIndex-1的所有代码单元。String toLowerCase()返回一个新字符串。这个字符串将原始字符串中的所有大写字母改成了小写字母。String toUpperCase()返回一个新字符串。这个字符串将原始字符串中的所有小写字母改成了大写字母。String trim()返回一个新字符串。这个字符串将删除了原始字符串头部和尾部的空格。
3.6.8阅读联机API文档
略
3.6.9构建字符串
有时候需要使用较短的字符串构建字符串,例如按键或来自文件中的单词。采用字符串连接的方式达到次目的的效率比较低。每次连接字符串,都会构建一个新的String对象,既耗时,又浪费空间。使用StringBuilder类就可以避免此问题发生。
步骤:
首先构建一个空的字符串构建器:
StringBuilder builder = new StringBuilder();当需要添加内容时,调用append方法。
builder.append(ch); // appends a single character<pre name="code" class="java">builder.append(str); // appends a string在需要构建字符串时就调用toString方法。
String completedString = builder.toString();
3.7输入输出
3.7.1读取输入
输出到“标准输出流”(即控制台窗口),调用System.out.println。
读取“标准输入流”,首先构造Scanner对象,并与“标准输入流”System.in关联。
Scanner in = new Scanner(System.in);之后使用Scanner类的各种方法实现输入操作。
读入一行:
System.out.print("What is your name?");String name = in.nextLine();读取一个单词(以空白符分割):
String firstname = in.next();读取一个整数:
System.out.print("How old are you?");String name = in.nextInt();读取一个浮点数调用in.nextDouble方法。
※Scanner类定义在java.util包中。当使用的类不是定义在java.lang包中时,一定要使用import指示字讲相应的包加载进来。
输入输出练习(InputTest.java):
import java.util.*;/* * This program demonstrates console input. * @version 1.0 * @author XXX * */public class InputTest {public static void main(String[] args){Scanner in = new Scanner(System.in);// get first inputSystem.out.print("What is your name?");String name = in.nextLine();// get second inputSystem.out.print("How old are you?");i age = in.nextInt();// display output on consoleSystem.out.println("Hello, " + name + ".Next year, you'll be " + (age + 1));}}
Scanner类不适用于从控制台读取代码。应使用Console类读取密码:
Console cons = System.console();String usrname = cons.readLine("User name: ");char[] passwd = cons.readPassword("Password: ");
※需要注意的一点,上述三行代码只能在控制台下运行,在Eclipse IDE下运行会出错。原因如下:
java.io.Console 这个类是 JDK 6 中新增的类库,用于操作系统的控制台,系统的控制台只能在操作系统原生的控制台中使用,不能在 IDE 的控制台中使用,因为 IDE 中的控制台是经过重定向的。
3.7.2格式化输出
System.out.printf()方法,用法与C的printf方法相同。
例如:
System.out.printf("Hello, %s, Next year, you'll be %d", name, age);
※可以使用s转换符格式化任意的对象。对于任意实现了Formattable借口的对象都将调用formatTo方法;否则将调用toString方法,它可以将对象转换为字符串。
另外,还可以给出控制格式化输出的各种标志。
System.out.printf("%,.2f", 10000.0 / 3.0);
上述代码打印:3333.33
可以使用多个表示,例如,“%,(.2f”使用分组的分隔符并将负数括在括号内。
printf方法还可以按照一定格式打印日期和时间。
例如:
System.out.printf("%tc", new Date());
上述语句将会按照下面格式打印当前日期和时间:
Sat Nov 22 17:31:25 CST 2014
从上表中可以看到,某些格式只给除了指定日期的部分信息。例如,只有日期或月份。如果想对日期的多个部分进行格式化的话,可以使用一个格式化的字符串来指出要被格式化的参数索引。索引必须紧跟在%后,并以$终止。
例如:
System.out.printf("%1$s %2$tB %2$te, %2$tY", "Due date:", new Date());
输出:
Due date: November 22, 2014
※参数索引从1开始,而不是从0开始。
3.7.3文件输入与输出
读取文件:
java.util.Scanner
java.nio.file.Paths
Scanner in = new Scanner(Paths.get("testFIleIO"));※如果文件名中包含反斜杠,就要在每个反斜杠之前再加一个额外的反斜杠“c::\\mydirectory\\myfile.txt”。
写入文件:
java.io.PrintWriter
PrintWriter out = new PrintWriter("testFileIO");
如果文件不存在,就创建该文件。
3.8控制流程
Java没有goto语句,但break语句可以带标签,可以利用它实现从内层循环跳出的目的。
3.8.1块作用域
块可以嵌套,但是不能在嵌套的两个块中声明同名的变量。
例如,下面代码不能够通过编译。
public static void main(String[] args){ int n; ... { int k; int n; // ERROR--can't redefine n in inner block }}
※在C++中可以在嵌套的块中重定义一个变量,但是在Java中不行。
3.8.2条件语句
同C/C++,略。
3.8.3循环
同C/C++,略。
3.8.4确定循环
同C/C++,略。3.8.5多重选择:switch语句
从Java SE7开始,case标签还可以是字符串字面量。
例如,
String input = ...;switch (input.toLowerCase()){case "yes": // OK since Java SE 7 ... break;...}
3.8.6中断控制流程语句
Java提供一条带标签的break语句,用来支持类似于goto语句的功能,跳出多重嵌套的循环语句。
※标签必须放在希望跳出的最外层的循环之前,并且必须紧跟一个冒号。
Scanner in = new Scanner(System.in);int n;read_data:while (...)// this loop statement is tagged with the label{...for (...)// this inner loop is not labeled{System.out.print("Enter a number >= 0:");n = in.nextInt();if (n < 0)// should never happend-can't go onbreak read_data;// break out of read_data loop...}}// this statement is executed immediately after the labeled breakif (n < 0)// check for bad situation{// deal with bad situation}else{// carry out normal processing}
如果输入有误,通过执行带标签的break跳转到带标签的语句块末尾。对于任何使用break语句的代码都需要检测循环时正常结束还是由break跳出。
标签可以应用到任何语句中,用于跳出语句块。不能用于跳入语句快。
continue语句将控制转移到最内层循环的首部。
3.9大数值
java.math包中提供了两个处理大数值的类:BigInteger和BigDecimal。BigInteger类实现了任意精度的整数运算,BigDecimal实现了任意精度的浮点数运算。
使用静态的valueOf方法可以将普通的数值转换为大数值:
BigInteger a = BigInteger.valueOf(100);
在大数值的运算时,不能使用熟悉的算数运算符(如: +, - ,×, / )处理大数值。必须使用大数值类中提供的add和multiply方法。
※Java语言没有像C++一样提供运算符重载的功能。
大数值计算的例子:
import java.math.*;import java.util.*;/* * This program uses big numbers to compute the odds of winning the grand prize in lottery. * @version 1.0 * @author XXX * */public class BigIntegerTest {public static void main(String[] args){Scanner in = new Scanner(System.in);System.out.print("How many numbers do you need to draw ?");int k = in.nextInt();System.out.print("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) * */BigInteger lotteryOdds = BigInteger.valueOf(1);for (int i = 1; i <= k; i++){lotteryOdds = lotteryOdds.multiply(BigInteger.valueOf(n - i + 1)).divide(BigInteger.valueOf(i));}System.out.print("Your odds are 1 in " + lotteryOdds + ". Good luck!");}}
3.10数组
数组的声明,int[] a;
或
int a[];
大多数Java程序员喜欢第一种风格,因为可以将数组int[]与变量int区分开。
初始化: int[] a = new int[100];
※数组大小不要求是常量。
3.10.1 for each循环
格式:for ( variable : collection ) statement;
定义一个变量用于暂存集合中的每一个元素,并执行相应的语句(或语句块)。collection这一集合表达式必须是一个数组或一个实现了Iterable接口的类对象。
for each语法比之前的for语法更加简介,不容易出错(无需关心数组下标是否有效)。
3.10.2数组初始化及匿名数组
■创建同时赋初值:
int[] smallPrimes = {2, 3, 5, 7, 11, 13};
此时不需要使用new。
■初始化匿名数组
new int[] {2, 3, 5, 7, 11, 13};使用此方法可以在不创建新变量的情况下重新初始化一个数组。
例如,
smallPrimes = new int[] {2, 3, 5, 7, 11, 13};
3.10.3数组拷贝
Java允许将一个数组变量拷贝给另一个数组变量。此时,两个变量将引用同一数组:
int[] luckNumbers = smallPrimes;luckNumbers[5] = 12; // now smallPrimes[5] is also 12
如果希望将一个数组的所有值拷贝到一个新的数组中。要使用Arrays类的copyOf方法。
int[] copiedLuckyNumbers = Arrays.copyOf(luckNumbers, luckNumbers.length);
第二个参数时新数组的长度,这个方法通常用来增加数组的大小。如果数组元素是数值型,那么多余的元素被赋值为0.如果是布尔型,则是false。
※Java的数组类似于C++的数组指针。
3.10.4命令行参数
略。
3.10.5数组排序
可以使用Arrays.sort方法,这个方法使用了优化的快速排序算法。
排序程序:
import java.util.*;/* * This program demonstrates array manipulation. * @version 1.0 * @author XXX * */public class LotteryDrawing {public static void main(String[] args){Scanner in = new Scanner(System.in);System.out.print("How many numbers do you need to draw?");int k = in.nextInt();System.out.print("What is the highest number you can draw?");int n = in.nextInt();// fill an array with numbers 1 2 3 ...nint[] numbers = new int[n];for (int i = 0; i < numbers.length; i++){numbers[i] = i + 1;}// draw k numbers and put them into a second arrayint[] result = new int[k];for (int i = 0; i < result.length; i++){// make a random index between and n - 1int r = (int)(Math.random() * n);// pick the element at the random locationresult[i] = numbers[r];// make the last element into the random locationnumbers[r] = numbers[n - 1];n--;}// print the sorted arrayArrays.sort(result);System.out.println("Bet the following combination. It'll make you rick!");for (int r : result)System.out.println(r);}}
3.10.6多维数组
注意:
for each循环语句不能自动处理二维数组的每一个元素。它是按照行,也就是一维数组处理的。要想访问二维数组的每一个元素,需要使用两个for each循环嵌套。
例如,
for (double [] row : a) for (double value : row) do something withw value
要想快速打印一个二维数组的数据元素列表,可以使用:
System.out.println(Array.deepToString(a));
3.10.7不规则数组
Java中实际上没有多维数组,只有一维数组。多维数组被解释为“数组的数组”。
因此Java可以存在不规则数组,即多维数组的每一位指向的数组的大小可以不同。
第三章完毕!
- [Java核心技术]学习笔记--第三章
- java核心技术卷I-第三章学习笔记
- 《JAVA 核心技术 基础知识》第三章 笔记
- Java多线程编程核心技术第三章笔记
- java核心技术第三章(笔记)
- Java核心技术学习笔记
- Java核心技术学习笔记
- Java核心技术-学习笔记
- 《java核心技术》学习笔记
- JAVA核心技术学习笔记
- java核心技术学习笔记
- [Java核心技术]学习笔记--第二章
- Java核心技术学习笔记第五章
- java核心技术学习笔记-第五章-继承
- FirstSample相关 《Java核心技术:卷1》第三章笔记
- 高手Java核心技术学习笔记
- 高手Java核心技术学习笔记
- Java核心技术学习笔记(一)
- Android 高仿微信头像截取 打造不一样的自定义控件
- TCP协议---建立连接
- TCP协议---关闭连接
- 建造者模式
- 常用Python第三方库
- [Java核心技术]学习笔记--第三章
- hdoj1018_Big Number(大数阶乘位数)
- Android 屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最佳方案
- Markov chain马氏链名词理解
- C++实现有向权图的基本操作,界面友好,操作方便,运行流畅
- jsp 在提交内容后的出现乱码 解决
- running android lint has encountered a problem
- java中的运算符
- 【leetcode 二叉树路径和】Path Sum 和 Path Sum II