天天看点

Java学习笔记(一)Java核心技术阅读笔记3.Java的基本程序设计结构

写在前面,将这里当成移动的笔记本来使用,不喜勿喷。

文章目录

  • 3.Java的基本程序设计结构
    • 3.1一个简单的Java程序
    • 3.2注释
    • 3.2数据类型
      • 3.2.1 整型
      • 3.2.2 浮点型
      • 3.2.3 char类型
      • 3.2.4 Unicode和char类型
      • 3.3.5 boolean类型
    • 3.4 变量
      • 3.4.1 变量初始化
        • 3.4.2 常量
    • 3.5 运算符
      • 3.5.1 数学函数和常量
      • 3.5.2 数值类型之间的转换
      • 3.5.3 强制类型转换
      • 3.5.4 结合赋值和运算符
      • 3.5.5 自增与自减运算符
      • 3.5.6 关系和布尔运算符
      • 3.5.7 位运算符
      • 3.5.8 括号与运算符级别
      • 3.5.9 枚举类型
    • 3.6 字符串
      • 3.6.1 子串
      • 3.6.2 拼接
      • 3.6.3 不可变字符串
      • 3.6.4 检测字符串是否相等
      • 3.6.5 空串与NULL串
      • 3.6.6 码点与代码单元
      • 3.6.7 String API
      • 3.6.8 阅读联机API文档
      • 3.6.9 构建字符串
    • 3.7 输入输出
      • 3.7.1 读取输入
      • 3.7.2 格式化输出
        • 比较常用的几个
      • 3.7.3 文件输入与输出
        • 读取
        • 写入
        • 可能发生的异常
    • 3.8 控制流程
      • 3.8.1 块作用域
      • 3.8.2 条件语句
      • 3.8.3 循环
      • 3.8.4 确定循环
      • 3.8.5 多重选择:switch语句
      • 3.8.6 中断控制流程语句
        • break
        • continue
    • 3.9 大数值
    • 3.10 数组
        • 初始化
      • 3.10.1 for each 循环
      • 3.10.2 数组初始化以及匿名数组
      • 3.10.3 数组拷贝
      • 3.10.4 命令行参数
      • 3.10.5 数组排序
      • 3.10.6 多维数组
      • 3.10.7 不规则数组
    • 总结一些知识
      • 输出数组的几种方式

3.Java的基本程序设计结构

3.1一个简单的Java程序

public class FirstSample {
    public static void main(String[] args)
    {
        System.out.println("We will not use 'Hello World!'");
    }
}
           

几个规定:

  • 区分大小写
  • 类名骆驼命名法
  • 名字必须以字母开头
  • 源代码的文件名必须与公共类名相同,也就是说这个文件必须命名为

    FirstSample.java

    -

    javac FirstSample.java

    后,会产生一个名为

    FirstSample.class

    的文件
  • 之后在

    java FirstSample

    注意不要带class即可运行。
  • Java虚拟机从指定类的

    main

    方法开始执行,所以必须有一个

    main

    方法

中间的输出语句,调用了

System.out

对象的

println

方法

3.2注释

// 单行注释
/*
多行注释
*/
/**
* 自动生成文档注释,左边的这个星是自动生成的
*/
           

3.2数据类型

8种基本类型,4种整型,2种浮点,1种char

3.2.1 整型

类型 存储需求 取值范围
int 32位 − 2 31 -2^{31} −231~ 2 31 − 1 2^{31}-1 231−1
short 16位 − 2 15 -2^{15} −215~ 2 15 − 1 2^{15}-1 215−1
long 64位 − 2 63 -2^{63} −263~ 2 63 − 1 2^{63}-1 263−1
byte 8位 − 2 7 -2^{7} −27~ 2 7 − 1 2^{7}-1 27−1
  • 长整型后缀L或者l
  • 十六进制数前缀0x或者0X
  • 二进制数前缀0b或者0B。例如 0b1001 就是9
  • 从java7开始,还可以为数字加下划线便于阅读,编译器会自动去除

    1_000_000

    0b111_0100

3.2.2 浮点型

类型 存储需求 取值范围
float 32位
double 64位
  • float

    后面有F或者f,没有的话默认为

    double

    类型
  • double

    后面没有或者加D,d
浮点数不适用于无法接受误差的金融领域,使用System.out.println(2.0-1.1)得到的是0.899999999,不是0.9,因为二进制无法精确表示分数1/10,如果在计算中不允许有任何误差,应该使用BigDecimal类。

3.2.3 char类型

使用单引号括起来,双引号是字符串。

  • char可以表示为十六进制 从

    \u0000

    \Uffff

  • 要当心注释中的\u也会造成错误

3.2.4 Unicode和char类型

  • 由于编码原因,最好不要使用char类型,除非确实需要处理UTF-16代码单元,最好用字符串作为抽象数据类型处理。

3.3.5 boolean类型

false

true

,整数型和布尔值之间不能相互转换!

3.4 变量

可以在一行中命名多个变量,但是不提倡。

3.4.1 变量初始化

3.4.2 常量

常用

final

指示常量,只能赋值一次,不能改变。

public class Constants
{
	public static void main(String[] args)
	{
		final double CM_PER_INCH = 2.54;
	}
}
           

希望在一个类的多个方法中使用常量

public class Constants
{
	public static final double CM_PER_INCH = 2.54;
	public static void main(String[] args)
	{
		System.out.println(CM_PER_INCH);
	}
}
           

3.5 运算符

/ %

  • /

    当两个数都是整数时表示整数除法,否则是浮点除法

3.5.1 数学函数和常量

java中没有幂运算,要借助Math类

import static java.lang.Math.*;

double y = Math.pow(x, a);
double x = Math.sqrt(z);
           

3.5.2 数值类型之间的转换

转为大的 double > float > long > int

3.5.3 强制类型转换

// 去尾
double x = 9.997;
int nx = (int)x;
// 如果想四舍五入
int nx = (int)Math.round(x);
           
  • 不要在布尔类型和任何数值类型之间进行转换

3.5.4 结合赋值和运算符

  • += 、×=, %=

3.5.5 自增与自减运算符

++, --,同样有前缀和后缀之分,建议不要在表达式中使用。

3.5.6 关系和布尔运算符

==, !=, &&, ||, ?:运算符

  • &&

    会优先计算左边的,左边为真才会计算右边的

    x!=0 && 1/x

    避免除0
  • ||

    左边为

    true

    的话会自动为真,不会计算右边

3.5.7 位运算符

&, |, ^(“xor”), ~(“not”)

int fourthBitFromRight = (n & 0b1000) / 0b1000
// 第四位为1则返回1,否则返回0
           

除此之外,还有

<<

>>

表示左移和右移

  • >>

    会用符号位填充,

    >>>

    会用0填充高位

3.5.8 括号与运算符级别

  • &&

    优先级高于

    ||

  • +=

    是右结合

3.5.9 枚举类型

enum Size {SMALL, MEDIUM, LARGE, EXTRA_LARGE};
Size s = Size.MEDIUM; // 只能取某个枚举值
           

3.6 字符串

从概念上讲,字符串是Unicode字符序列,

‘Java\u2122’

由5个Unicode字符构成。Java没有内置的字符串类型,而是再标准Java类库中提供了一个预定义类

String

3.6.1 子串

String greeting = "Hello";
String s = greeting.substring(0, 3);// 由Hel组成的子串
           

3.6.2 拼接

  • 允许使用

    +

    拼接,中间无空格
  • 将一个字符串与一个非字符串进行拼接时,后者转化为字符串。常用与输出中。
int age = 13;
String rating = "PG" + age; // "PG13"
           

3.6.3 不可变字符串

String类没有提供修改字符串的方法,所以要将"Hel"修改为Help!只能通过如下方法。

表面上看生成一个新的字符串低效,但是编译器可以让字符串共享。

3.6.4 检测字符串是否相等

不可以使用

==

来判断。

s.equals(k); 
s.equalsIgnoreCase(k); //无视大小写
           
如果虚拟机始终将相同的字符串共享,则可以用==比较,但是只有字符串常量是共享的,而+和substring等操作产生的结果并不共享。

3.6.5 空串与NULL串

// 判断是否为空的两个方法
if (str.length()==0)
if (str.equals(""))
// 判断是否为NULL
if (str==null)
           

3.6.6 码点与代码单元

3.6.7 String API

3.6.8 阅读联机API文档

3.6.9 构建字符串

有时需要几个较短的字符串,构建一个字符串。但是效率很低,因为每次都会构建一个新的String对象,既耗时又浪费空间。可以使用

StringBuilder

类避免这个问题。

// 首先构建一个空的字符串构建器
StringBuilder builder = new StringBuilder();
// 每次需要添加一部分内容时,就调用append方法
builder.append(ch);
builder.append(str);
// 调用时就调用toString方法,就可以得到一个String对象
String completeString = builder.toString();
           

3.7 输入输出

3.7.1 读取输入

标准输入流

System.in

import java.util.*;
// 首先构造一个Scanner对象,并与标准输入流关联
Scanner in = new Scanner(System.in);
// 然后就可以实现各种输入操作了
System.out.print("What is your name?");
String name = in.nextLine(); //读取一行
String name = in.next(); // 读取一个单词,到第一个空格为止
System.out.print("How old are you?");
int age = in.nextInt(); // 读取一个整数 nextDouble()
           

因为输入是可见的,所以不适合读取密码,java特别引入了Console类实现这个目的。

3.7.2 格式化输出

System.out.printf("%8.2f", x); // 这个数字占8位,右对齐,小数点后保留2位
System.out.printf("Hello %s, next year you will be %d", name, age);
           

也可以使用格式化的参数索引

System.out.printf("%1$s %2$tB %2$te, %2$tY", "Due data:", new Data());
System.out.printf("%s %tB %<te, %<tY", "Due data:", new Data()); // 输出相同
// Due data: Febraury 9, 2015
           
  • %

    $

    之间的部分就是格式化参数索引,注意这个索引从1开始
  • <

    指示前面格式的说明参数将被再次利用

比较常用的几个

  • %-x.yf

    负号是左对齐,否则是右对齐,x是这个数字占的总位数 ,y是保留几位小数
  • %0,9.2f

    逗号是加入分隔符,每三位加一个逗号,0是自动用0补位
  • 标志要写在宽度前边(左边)

3.7.3 文件输入与输出

读取

  • 如果文件名中包含反斜杠,记得每一个反斜杠前再加一个反斜杠。

    c:\\mydirectory\\myfile.txt

  • 指定了UTF-8字符编码

写入

  • 如果文件不存在,自动创建一个文件
  • 读取和写入的路径都是相对于

    Java虚拟机启动路径

可能发生的异常

当读取一个不存在的文件或者写入一个不能被创建的文件名,会出错,所以在这里需要标注可能出现的错误, 使用

throw

语句,异常的处理在后面介绍。

public static void main(String[] args) throw IOException
{
	Scanner in = new Scanner(Paths.get("myfile.txt"), "UTF-8");
}
           

3.8 控制流程

条件语句和循环结构以及switch。

3.8.1 块作用域

块(block)就是由大括号括起来的若干条语句。

  • 不能在嵌套的两个块中声明同名变量。(不会覆盖,只会报错)

3.8.2 条件语句

if ()
{}
else if ()
{}
else
{}
           

3.8.3 循环

  • while
  • do while

3.8.4 确定循环

  • for

    要注意检测浮点数是否相等的时候,可能因为无法得到精确值永远无法结束。

因为0.1无法用二进制精确表示,所以x将从

9.999 999 999 999 98

跳到

10.099 999 999 999 98

  • 如果for循环体内部定义一个变量,这个变量不能在循环体之外使用
  • 不同的for循环体内部可以定义同名变量

3.8.5 多重选择:switch语句

顺序执行,所以必须有break,避免执行多个分支语句。

Scanner in = new Scanner(System.in);
System.out.print("Select an option (1, 2, 3, 4)");
int choice = in.nextInt();
switch (choice)
{
	case 1:
		...
		break;
	case 2:
		...
		break;
	default:
		...
		break;
}
           
// java se 7之后可以这么用 匹配string
String input = ...;
switch (input.toLowerCase())
{
	case "yes":
		...
		break;
}
           
// 枚举常量
Size sz = ...;
switch (sz)
{
	case SMALL: // 不需要使用sz.SMALL
		...
		break;
}
           

3.8.6 中断控制流程语句

break

  • break 可以跳出一层循环
  • 带标签的break,可以跳出多层循环
Scanner in = new Scanner(System.in);
int n;
read_data:
while(...)
{
	...
	for (...)
	{
		...
		if (...)
			break read_data;
		...
	}
}
           

命名标准:

  • 标签必须放在希望跳出的最外层循环之前。
  • 必须紧跟一个冒号。

continue

  • continue
  • 带标签的continue,用法和break一样

3.9 大数值

基本浮点数和整数的精度不能满足,则可以使用

java.math

中包含的很有用的类

BigInteger

BigDecimal

,实现了任意精度的整数和浮点数运算。

// 使用静态的方法将普通数值转化为大数值
BigInteger a = BigInteger.valueOf(100);
           

但是不能使用运算符号处理大数值,需要使用大数值类中的

add

multiply

方法。

BigInteger c = a.add(b);
BigInteger d = c.multiply(b.add(BigInteger.valueOf(2)));
           

3.10 数组

// 声明数组
int[] a; // 声明,并未初始化
int[] b = new int[100]; // 创建一个可以存储100个整数的数组

// 两种声明方式,推荐第一种
int[] a;
int a[];
           

初始化

数字数组所有值初始化为0,boolean初始化为false,对象数组初始化为null。

names.length

会返回数组的长度。

  • 创建数组后就不能改变其大小
  • 如果需要经常改变数组大小,应该使用另一种数据结构数组列表

3.10.1 for each 循环

for (int element: a)
	System.out.println(element);
           

a必须是数组或者是实现了Iterable接口的类对象。

  • 还有一个打印集合所有元素的简单方法
System.out.println(Arrays.toString(a));
// 这个方法返回一个包含数组元素的字符串,这些元素放在一个方括号内,并且用逗号隔开,就像数组那样
// [1, 2, 3, 4]
           

3.10.2 数组初始化以及匿名数组

一种创建数组并初始化的简写形式,不用写new

匿名数组

数组大小就是初始值的个数。

smallPrimes = new int[] {1, 2, 3, 4, 5};
// 这句话是下面这两句的简写
int[] anonymous = {1, 2, 3, 4, 5};
smallPrimes = anonymous;
           

java中允许数组长度为0,这个和null不同。

3.10.3 数组拷贝

简单的使用等号进行拷贝的话,会让两个变量指向同一个数组,想要深拷贝,必须使用

Arrays

类的

copyOf

方法。

第二个参数为长度,可以用来增加数组长度,多出的部分将赋值为0(false,null),如果这个长度小于原数组长度,则只拷贝前面的元素。

3.10.4 命令行参数

我们注意到每一个main函数都带有一个字符串数组

args

,所以main函数可以接受参数。可以使用

args[0]

,

args.length

来进行调用。

在命令行中输入如下命令

java filename -g cruel world
           

相当于向args中存入三个字符串

-g cruel world

3.10.5 数组排序

Arrays.sort(a)

使用

sort

方法排序。

Math.random()

可以生成一个0-1的数,不包含1,包含0

3.10.6 多维数组

声明一个二维数组

double[][] balances;
balances = new double[NYEARS][NRATES];

int[][] magicSquare = {
	{16, 3, 2, 13},
	{5, 10, 11, 8},
	{9, 6, 7, 12},
	{4, 15, 14, 1}
};

banlances.length == NYEARS;
banlances[i].length == NRATES;
           

想快速打印一个二维数组,可以使用

Arrays.deepToString(a);
// 输出格式
// [[1], [2], [3]]
           

3.10.7 不规则数组

数组的每一行有不同的长度。

总结一些知识

输出数组的几种方式

  • for each 循环
for (int i: array)
	System.out.print(i);
           
  • 普通的for循环
  • Arrays方法
System.out.println(Arrays.toString(array)); // 输出的是用方括号括起来的,逗号隔开的结果
System.out.println(Arrays.deepToString(array)); // 输出的是多维数组,[[],[],[]]这样形式的