《java语言程序设计》笔记(一)

来源:互联网 发布:踏步机不要扶手知乎 编辑:程序博客网 时间:2024/05/17 23:22

前言:本文是在看《java语言程序设计》(英文版) (Y.Daniel Liang著 ISBN 978-7-111-36122-0)时自己记下的笔记,由于水平有限,翻译有不当之处。

Chapter1 Introduction to Computers, Programs, and Java

 

Chapter2 Elementary Programming

java是大小写敏感的。

 

+号是作连接字符串操作时,如果有一个操作数不是字符串时,该操作数会被自动转换成字符串再继续执行连接操作。

 

字符串连接不能跨行,如下表达是错误的:

System.out.println(“java

note”);

应该表达如下:

System.out.println(“java” +

“note”);

 

java没有直接支持从控制台输入数据,但是可以使用Scanner类来创建一个对象,从System.in中读取数据,如下所示:

Scanner input = new Scanner(System.in);

一个Scanner对象可以调用它的方法来读入数据,常用的读入数据的方法有:

nextByte()

nextShort()

nextInt()

nextLong()

nextFloat()

nextDouble()

next() //读入一个字符串,以空格键作为结束

netxtLine() //读入一个字符串,以回车键作为结束

 

从控制台读入数据的一个例子:

Scanner input = new Scanner(System.in);

double radius = input.nextDouble();

 

标识符可以以$开头,但是标识符中不会使用$字符,因为按照惯例,$字符仅仅用在机械生成的源代码。

 

按照惯例,常量命名时字母全为大写。

 

原子数据类型:

byte 8

short 16

int 32

long 6 4

float 32

double 64

 

一般地,我们使用double类型来定义浮点数,因为doublefloat更精确。

 

java编译是对溢出不会有警告或错误的提示,所以对变量的值域一定要小心。

 

当两个整数相除时结果的小数部分会被忽略,如5/2 =2,如果要保留小数部分,则除数或被除数最少有一个是浮点数,如5.0/2 = 2.5

 

要表示八进制常数时,八进制数前边加一个0zero),如011 = 9

要表示十六进制常数时,十六进制数前边加上前缀0xzero x,0xffff = 65535

 

默认浮点常数是double类型,如果要指定为float型可以在常数后边加fF,如1.0f,如果要指定为double类型可以在常数后边加dD,如1.0d

 

科学记数法:

1.23456e+2 = 1.23456e2 = 1.23456 X 102

1.23456e-2 = 1.23456 X 10-2

Ee都可以)

 

可以用System类中的currentTimeMillis方法获取当前时间,该时间是代表由19701100:00EST美国东部标准时间)开始到当前的总毫秒数,要获取当前时分秒可按以下方法计算:

当前的总毫秒数/1000 = 当前的总秒数

当前的总秒数%60 = 当前的秒

当前的总秒数/60 = 当前的总分钟数

当前的总分钟数%60 = 当前的分

当前的总分钟数/60 = 当前的总小时数

当前的总小时数%60 = 当前的时

 

运算时扩大一个变量的类型会自动地执行,但缩小一个变量的类型必须显式的指明。

 

+= 之类的连写操作符中间不能有空格,如+ = +=中间有一个空格)是错误的。

 

强制类型转换只是临时的,不会真正的改变该变量的类型。

 

Math类中的pow(a,b)方法可以用来计算ab。

 

为了避免错误,nextLine()不能使用在nextByte(), nextShort(), nextInt(), nextLong(), nextFloat(), nextDouble()next()之后。

 

命名习惯:

1、变量和方法习惯用小写字母命名,如果有多个单词,把多个单词连接起来,除了第一个单词以外,每个单词的首字母用大写,如showInputDialog

2、类习惯用大写字母做开头,多个单词时和变量和方法的命名一样,但保持首字母是大写。如JOptionPane

3、常量习惯用全大写字母命名,如有多个单词,用下划线”_”连接,如MAX_VALUE

4、命名时单词用全写比用缩写好,如numberOfStudentsnumStuds, numOfStuds, 或者numOfStudents都要好。

 

Integer类中的parseInt方法可以把数字字符串转换为整型数字。

Double类中的parseDouble方法可以把数字字符串转换为浮点型数字。

 

 

Chapter3 Selections

flagboolean类型,判断条件使用if(flag)if(flag == true)要好,因为书写flag == true时有可能漏写一个等于号而导致错误。

 

使用Math类中的random方法可以获取一个0.0<= d <= 1的随机数。

 

1 <= number <= 3 的表达方式是错的,因为虽然运算1 <= number 是正确的,但该操作得到的是boolean类型的结果,boolean类型与3<=比较操作将会出错。所以应该写作 (number >= 1) && (number <= 3)

 

boolean类型不能强制转换为其他任何的类型。

 

格式化输出printf

%b    a boolean value

%c    a character

%d    a integer

%f    a floating-point number

%e    a number in standard scientific notation

%s    a string

 

%5d  能指定输出的位数为5位,不够5位的在左边用空格补齐,超过5位的长度会自动增加;

%10.2f 能指定整数部分为10位,小数部分为2位,同样不够长度的会用空格补齐,超过的自动增加长度;

%后加数字格式化输出默认是右对齐的,如果添加负号”-“,如 %-5d 则默认是左对齐,如果不够5位会在右边添加空格。

 

要输出%号要写成%%

 

 

Chapter4 Loops

 

 

Chapter5 Methods

我们说的定义(define)和声明(declare)是有一点小区别的,定义(define)通常是指定义一个项目,而声明则包括为声明的变量分配内存去存储数据,所以我们会说“定义一个方法(define a method)”和“声明一个变量(declare a variable)”。

 

对于一个值返回方法,return语句是必须的,要小心下面的错误:

public static int sign(int n) {

  if(n > 0) {

   return 1;

}

  else if(n == 0) {

   return 0;

  }

  else if(n < 0) {  //编译器会认为如果都不符合条件(即使我们知道这里至少有return -1;     //一个条件成立),则没有return语句,所以编译错误

  }

}

应改为如下:

public static int sign(int n) {

  if(n >0)

return 1;

  else if (n == 0) P

    return 0;

  else 

return -1;

}

 

重载(overloading)

重载:两个相同名字的方法通过不同的参数列表去区别。

重载必须是参数列表不同,仅仅是返回值类型不同不能构成重载。

 

参数列表也是局部变量。

 

for循环开头括号内定义的变量有效范围仅在循环体内。

 

嵌套关系内不能定义同名的变量。

如下代码是正确的:

public static void method1() {

  int x = 1;

  int y = 1;

  for(int i=1; i<10; i++) {

   x+=i;

  }

  for(int i=1; i<10; i++) {

y +=i;

}

}

如下代码是错误的:

public static void method2() {

  int i = 1;

  int sum = 0;

  for(int i=1; i<10; i++) { // 这里i重复定义了

   sum += i;

  }

}


Chapter6 Single-Dimensional Arrays

声明一个数组变量

elementType[] arrayRefVar;

如 double[] myList;

也可以沿用C的格式如下:

elementType arrayRefVar[]  但是在java中更习惯用前一种格式

 

不像声明一个原始数据类型的变量,声明一个数组变量不会分配内存空间,声明的数组变量仅仅是一个引用,如果该数组变量没有引用一个数组,它的初始值是null。如果要分配内存空间,则要使用new关键字,格式如下:

arrayRefVar = new element Type[arraySize];

也可以声明与分配放在同一条语句中,如

elementType[] arrayRefVar = new elementType[arraySize];

或者 elementType arrayRefVar = new elementType[arraySize]; //该格式不常用

 

虽然准确的说声明的数组变量应该叫数组引用,而new elementType[arraySize]分配的内存空间叫数组,但一般地为了简化我们都直接称声明的数组变量为数组。

 

可以用arrayRefVar.length 获取数组长度。

 

当一个数组被创建时,他们的默认值分别是:数字类型的为0,字符类型的为’\u0000’,布尔型的为false

 

数组初始化的格式如下:

elementType[] arrayRefVar = { value0, value1, ……, valuek};

如:double[] myList = {1.9, 2.9, 3.5, 3.5}; //没有new关键字

这个写法等同于:

double[] myList = new double[4];

myList[0] = 1.9;

myList[1] = 2.9;

myList[2] = 3.4;

myList[3] = 3.5;

 

如果使用数组初始化必须把声明、创建和初始化数组写在同一个语句中,如下边的编写使错误的:

double[] myList;

myList = {1.9, 2.9, 3.4, 3.5};

 

对于字符数组,可以使用一条打印语句将其输出,如:

char[] city = {‘D’, ‘a’, ‘l’, ‘l’, ‘a’, ‘s’};

System.out.println(city);

 

For-each 循环

java提供一种简便的for循环,格式如下

for(elementType element: arrayRefVar) {

  //Process the element

}

例如要显示myList数组中的所有元素可以写作如下:

fordouble u: myList) {

  System.out.println(u);

}

可以理解为“对每一个在myList数组中的元素u执行System.out.println(u)操作”,要注意u的类型必须与myList数组中的元素的类型相同。

 

可以使用java.lang.System类中的 arraycopy方法复制数组的元素,该方法的参数如下:

System.arraycopy(sourceArray, src_pos, targetArray, tar_pos, length);

如把数组A复制至数组B

System.arraycopy(A, 0, B, 0, A.length);

数字0表示开始复制的数组下标。

要注意arraycopy方法并不会给targetArray分配空间,所以必须确保复制前targetArray已分配空间。

arraycopy不符合java命名规则,规范的应该是arrayCopy)。

 

匿名数组

new elementType[]{value0, value1, …, valuek};

这样创建出来的临时数组成为匿名数组,没有引用指向该数组,所以只能一次性使用。

 

数组传参

原始数据的传参是值传递,在方法中只会改变形参,不改变实参;

但是数组传递的是引用,也就是说方法中对形参数组的修改,也会导致实参数组改变,因为其修改的是同一个内存地址。

 

JVM把数组存放于堆(heap)内存中,堆内存使用动态内存分配技术按随意的顺序分配和释放内存。

 

有如下代码

public class Test {

  publicstaticvoidmainString[] args) {

int x = 1;

int [] y = new int [10];

m(x, y);

System.out.println(“x is” + x);

System.out.println(“y[0] is “ + y[0]);

  }

 

  public static void m (int number, int [] numbers) {

number = 1001;

number[0] = 5555;

  }

}

运行结果为

x is 1

y[0] is 5555

代码的内存分配图如下


我们可以把相同数据类型的变量作为数组参数方便地传入方法中,方法的参数声明如下

typeName…parameterName

例:

public class VarArgsDemo {

  public static void main(String[] args) {

printMax(34, 3, 3, 2, 56.5);  //printMax方法会把多个参数看作一个数组

printfMax(new double[] {1, 2, 3});

 }

 

 public static void printMax (double…numbers) {

if(numbers.length == 0) { 

       System.out.println(“No argument passed”) ;

       return ;

}

double result = numbers[0];

for(int i=1; i< numbers.length; i++) {

  if(numbers[i] > result)

    result = numbers[i];

}

System.out.println(“The max value is” + result);

}

}

 

java.util.Arrays类中包含多种静态的方法供数组的排序、查找、比较和填充。这些方法被各个原始数据类型重载。

可以使用sort方法对整个或部分的数组进行排序。如

double[] numbers = {6.0, 4.4, 1.9, 2.9, 3.4, 3.5};

java.util.Arrays.sort(numbers); //对整个数组排序

char[] chars = {‘a’, ‘A’, ‘4’, ‘F’, ‘D’, ‘P’};

java.util.Arrays.sort(chars, 1, 3); //char[1]char[3-1]的数组部分进行排序。

可以使用equals方法检查两个数组是否相等,但是要注意元素的顺序也相同才相等,对于下边三个数组,list1list2是相等的,但list1list3不相等。

int[] list1 = {2, 4, 7, 10};

int[] list2 = {2, 4, 7, 10};

int[] list3 = {4, 2, 7, 10};

可以使用fill方法填充整个或部分数组,如

int[] list1 = {2, 4, 7, 10};

int[] list2 = {2, 4, 7, 10};

java.util.Arrays.fill(list1, 5); //list1整个个数组填充5

java.util.Arrays. fill(list2, 1, 3, 8); //list2[1]list2[3-1]的部分填充8

 

 

Chapter7 Multidimensional Arrays

二维数组的声明格式

elementType[][] arrayRefVar;

elementType arrayRefVar[][]; //允许,但不好

 

二维数组的声明并分配空间

elementType[][] arrayRefVar = new elementType[length][length];

如 int matrix = new int[5][5];

 

与一维数组一样,可以用数组初始化去声明、创建和初始化二维数组。

如:int[][] array = {

       {1, 2, 3},  //不要遗漏后边的逗号

       {4, 5, 6},

       {7, 8, 9}

};

 

二维数组的每一行都是一个数组,所以每一行可以拥有不同的长度,如可以创建如下二维数组:

int [][] triangleArray = {

  {1, 2, 3, 4, 5},

  {2, 3, 4, 5},

  {3, 4, 5},

  {4, 5},

  {5}

};

如果事先不知道值,也可以创建如下的二维数组:

int [] triangleArray = new int[5][];

triangleArray[0] = new int [5];

triangleArray[1] = new int [4];

triangleArray[2] = new int [3];

triangleArray[3] = new int [2];

triangleArray[4] = new int [1];

new 二维数组时第一个指针必须指定,如new int[5][]中的5不能忽略,如果写成int[][]是错误的。


0 0