目录
一个简单的Java程序
public class FirstSsample{
public static void main(String[] args){
System.out.println("Hello World");
}
}
- Java区分大小写
- Java应用程序中的所有内容都必须放置在类中
- 关键字class后面紧跟类名,须以字母开始,但不能使用Java保留字/关键字
- 标准的命名规范为单词首字母大写
- 源代码的文件名须与类名一致,并以.java作为文件扩展名,注意大小写
注释
- // 单行注释
- /* 多行注释 */
- /** 可以用来自动生成文档 */
数据结构
Java是一种强类型语言,所以变量需要申明类型。
在Java中一共有8种数据类型,4种为整型,2种浮点型,1种用于表示Unicode编码的字符单元的字符类型char,1种用于表示真值的boolean类型。
整型
类型 | 存储需求 | 取值范围 |
long | 8字节 | -9 223 372 036 854 774 808 ~ 9 223 372 036 854 774 807 |
int | 4字节 | -2 147 483 648 ~ 2 147 483 647(正好超过20亿) |
short | 2字节 | -32 768 ~ 32 767 |
byte | 1字节 | -128 ~ 127 |
1、因为Java的数据类型所占据的字节数固定,与机器无关,不像C/C++,在16/32/64位机器中相同的数据类型却占据不同大小的字节数,对跨平台带来了难度,所以Java就解决了软件迁移中数据溢出等问题。
2、long型数值需要有一个 L或l 后缀(如 400000000000000L)
3、十六进制数值有一个前缀 0x/0X (如 0xCAFE)
4、八进制数值有一个前缀0 (如 010 对应八进制中的 8)
5、从 Java 7 开始,二进制可以通过加上前缀 0b/0B 来表示(如 0b1001 就是 9)
6、从 Java 7 开始,可以为数值字面量加下划线(如 1_000_000 表示100万),这些下划线仅仅用来进行位数的划分,更易读,Java编译器会去除这些下划线
浮点型
类型 | 存储需求 | 取值范围 |
float | 4字节 | 大约 +-3.402 823 47E +38F(有效位数为6 ~7位) |
double | 8字节 | 大约 +-1.797 693 134 862 315 70E + 308(有效位数为15位) |
1、double的数值精度是float的两倍(故也称作双精度数值);绝大多数都采用double类型
2、float类型的数值需要一个后缀 F/f(如 3.14F),没有后缀的(如3.14)默认为double类型
char类型
1、char类型需要用单引号扩起来,如‘A’是编码值为65所对应的字符常量。
2、char类型的值可以用十六进制的方式表示,其范围从 \u0000 到 \Uffff 。
Unicode和char
Unicode编码机制打破了传统字符编码机制的限制,在其之前存在许多的标准
美国的 ASC2⃣️、西欧语言中的 ISO 8859-1、俄罗斯的 KOI-8、中国的 GB 18030 和 BIG 5 等。
导致了标准不统一,故Unicode编码的目的就是要解决这个问题。在设计之初,人们认为两个字节的代码宽度足以对世界上各种语言的所有字符进行编码,并有足够空间进行扩展。在91年发布了Unicode1.0,当时仅占用65 536个代码值不到一半的部分。在设计Java是决定采用16位的unicode字符集,这样会比使用8位字符集的程序设计语言有很大的改进。
但是由于增加了大量的汉语、日语、韩语中的表意文字,现在16位的char类型已经不能满足描述所有unicode字符的需要了。Java解决这个问题的基本方法:
码点(code point)是指与一个编码表中的某个字符对应的代码值。在Unicode标准中,码点采用十六进制书写,并加上前缀U+,例如U+0041就是拉丁字母A的码点。
Unicode的码点可以分为17个代码级别(code plane)。第一个代码级别成为基本的多语言级别(basic multilingual plane),码点从 U+0000 到 U+FFFF,其中包括经典的Unicode代码;其余的16个代码级别码点从 U+10000 到 U+10FFFF,其中包括一些辅助字符(supplementary character)
UTF-16编码采用不同长度的编码表示所有Unicode码点。在第一个代码级别(基本的多语言级别)中,每个字符用16位(2字节)表示,通常被称为代码单元(code unit);而辅助字符采用一队连续的代码单元进行编码。这样构成的编码值落入基本的多语言级别中空闲的2048字节内,通常被称为替代区域(surrogate area)【U+D800 ~ U+DBFF 用于第一个代码单元,U+DC00 ~ U+DFFF 用于第二个代码单元】。这样设计,我们可以从中迅速地知道一个代码单元是一个字符的编码,还是一个辅助字符的第一或第二部分。
Java中,char类型描述了UTF-16编码中的一个代码单元。
不建议在程序中使用char类型,除非确实需要处理URF-16代码单元。最好将字符串作为抽象数据类型处理。
Boolean类型
1、boolean(布尔)类型有两个值:false和true,用来判定逻辑条件。
2、整型之和布尔值之间不能进行转换。
变量
1、Java声明变量后必须用赋值语句对变量进行显式初始化,千万不要使用为初始化的变量。
2、在Java中变量的声明尽可能地靠近变量第一次被使用的地方,是一种良好的程序编写风格
3、C++中区分定义和声明,Java中不进行区分。
//C++中
//定义一个变量
int I = 10;
//声明一个变量
extern int i;
常量
1、关键字final指示常量
2、常量只能被赋值一次
3、习惯上,常量名全大写
4、若希望一个常量被类中多个方法使用,可声明类常量(public表示其他类的方法也可以访问该常量)
public static final int i = 1;
运算符
1、在Java中,使用算术运算符+、-、*、/、%
2、15/2=7;15%2=1;15.0/2=7.5
3、整数/0会产生异常,浮点数/0=无穷大或NaN
4、对于使用strictfp关键字标记的方法必须使用严格的浮点计算来生成可再生的结果。
数学函数与常量
在Math类中,提供了许多数学函数:
1、平方根
double x = 4;
double y = Math.sqrt(x);
System.out.println(y); //prints 2.0
2、幂运算
double x = Math.pow(2,5); //2的5次幂
3、三角函数
Math.sin;Math.cos;Math.tan;Math.atan;Math.atan2;
4、指数函数以及其反函数——自然对数以及以10为底的对数
Math.exp;Math.log;Math.log10;
5、关于派和e的近似值
Math.PI;Math.E;
6、在原文件的顶部加上以下代码(静态引入),则可以不必在数学方法名和常量名前添加前缀“Math”
import static java.lang.Math.*;
数值类型之间的转换
char | ||||||
⬇︎ | ||||||
byte | ➡︎ | short | ➡︎ | int | ➡︎ | long |
↓ | ⬊↙︎ | ↓ | ||||
float | ➡︎ | double |
注:加粗箭头表示无信息丢失的转换,普通箭头表示有精度损失的转换
总结:
1、int/long转换为float都有可能导致精度损失
2、long转换为double可能导致精度损失
3、char可以无损失的转换为int
4、以上转换关系不论是否有无损失,都可以直接进行转换。即小单位可以直接转换为大单位,整型可以直接转换为浮点型,字符型可以直接转换为整型/浮点型。
强制类型转换(cast)
对于大单位转换为小单位,浮点型转换为整型,整型/浮点型转换为字符型,都需要强制类型转换。
double x = 9.99;
int y = (int)x; // y=9
double x = 9.99;
int y = (int)Math.round(x); // y=10,进行了四舍五入。
//Math.round方法返回long型数值,故需要(int)强制转换。
结合赋值和运算符
+=;-=;*=;/=;%=;
int x = 1;
x += 3.5; //x=4,结果与左侧类型不一致时,会自动进行强制类型转换(cast)
自增自减运算符
n++;n--;++n;--n;
1、n++,先用后加
2、++n,先加后用
关系和boolean运算符
condition ?expression1 :expression2
等价于
if(conditions){
expression1
}
else{
expression2
}
for example:
int x = 1;
x = x == 1 ? 2 : 0; //x=2
等价于
if(x == 1){
x = 2;
}
else{
x = 0;
}
位运算符
待补充
枚举类型
对于一些取值仅在有限集合内的变量,可以自定义枚举类型
enum Size {SMALL,MEDIUM,LARGE};
Size x = Size.SMALL;
//Size类型变量只能取限定值或null,null指变量还未设置任何值。
字符串
子串
String s = "Hello";
s = s.substring(0,3); //s="Hel",获取0,1,2位字符
拼装
//直接使用“+”号进行拼接
//若希望有分隔符进行分隔,则
String s = String.join("/","S","M","L","XL");
// s="S/M/L/XL"
检测字符串是否相等
String s = "Hello";
s.equals("Hello"); //为true
//不能使用“==“进行比较,因为”==“会比较两个字符串的地址是否相同。对于字符串常量来说是相同的,结果为true,但是对于”+“或substring来的字符串结果不是共享的,地址将不同,会得到false结果。
空串与null串
String s = ""; //空串
//判断空串
s.equals("");
if(s.length() == 0)
String s1 = null; //null串
//判断null串
if(s1 == null)
码点与代码单元
String s = "Hello";
//length方法返回采用UTF-16编码表示的给定字符串所需要的代码单元数量
s.length() //is 5
//要想得到实际长度,即码点数量,可以调用
int cpCount = s.codePointCount(0,s.length());
//获得字符串中固定位置的代码单元
char first = s.charAt(0) //first is 'H'
char last = s.charAt(4) //last is 'o'
//要想得到第i个码点:
int index = s.offsetByCodePoints(0,i);
int cp - s.codePointAt(index);
构建字符串
若希望通过许多短的字符串构建成一个大的字符串,通过“+“号连接字符串的效率比较低,浪费时间,也占用空间,因为每一次连接都会生成一个新的String对象,使用StringBuilder类就可以避免这个问题的发生
StringBuilder builder = new StringBuilder();
builder.append(ch);; //appends a single character
builder.append(str); //appends a string
String myString = builder.toString();
StringBuilder类的前身是StringBuffer,StringBuffer类的效率较低,但是它允许采用多线程的方式执行添加或删除字符的操作。若所有字符串在一个单线程中编辑,则推荐使用StringBuilder替代StringBuffer。
输入输出
读取输入
要想通过控制台进行输入,需要构造一个Scanner对象,并于“标准输出流”System.in关联。
import java.util.*;
Scanner scanner = new Scanner(System.in);
//输入一行内容
String s = scanner.nextLine();
//输入一个单词(以空格为分隔符)
String s = scanner.next();
//输入一个int数字
int a = scanner.nextInt();
若输入内容较为敏感,如密码,Java SE 6特别引入了Console类实现这个目的:
Console cons = System.console();
String username = cons.readLine("User Name:");
char[] passed = cons.readPassword("Password:");
格式化输出
System.out.printf();
文件输入和输出
要想对文件进行读取,就需要一个用File对象构建一个Scanner对象:
Scanner in = new Scanner(Paths.get("myfile.txt"),"UTF-8");
要想写入文件,则需要构架一个printwriter对象
PrintWriter out = new PrintWriter("myfile.txt","UTD-8");
//如果文件不存在,则创建该文件。
//可以像输出到System.out一样一样使用print、println、printf命令
out.print("Hello");
控制流程
1、if、while、for、switch等流程控制语句的使用
2、带/不带标签的break、continue运用
int total = 0;
int cost = 0;
Scanner in = new Scanner(System.in);
add_cost:
while(true){
System.out.print("Cost:");
cost = in.nextInt();
if(cost < 0)
break add_cost;
total += cost;19
System.out.println("Your total cost is:"+ total);
}
if(cost < 0){
System.out.println("Your cost can't less than 0");
}
大数值
若基本的整型和浮点型数值无法满足你的精度要求,那么可以使用java.math包中的两个很有用的类:BigInteger和BigDecimal,分别处理包含任意长数字序列的整数和浮点数运算。
使用静态的valueOf()方法可以将普通数值转换为大数值
BigInteger a = BigInteger.valueOf(100);
大数值的运算方法:
BigInteger c = a.add(c);
BigInteger d = c.multiply(b.add(BigInteger.valueOf(2))); //d=c*(b+2)
数组
//声明数组
//方法一:
int[] a;
//方法二:
int a[];
for each循环
形式为:for ( variable : collection ) statement
int[] a = {1,1,1,1,1};
for(int b : a){
System.out.print(b+",");
}
数组初始化与匿名数组
new int[] {1,1,1,1};
初始化了一个匿名数组,将该数组赋值给一个现有数组。可以实现不创建新变量的情况下重新初始化一个数组。
数组拷贝
若单纯使用“=”进行两数据的拷贝,则在内存空间中使用的是同一个数组地址,即指向同一个数组。
若想完全重新创建一个数组,而保留相同的值,则使用Arrays的copyOf()方法。
int[] copied = Arrays.copyOf(origin, origin.length); //第二个参数为新数组copied的长度
//这个方法也可以用来扩展或缩小数组大小,如:
origin = Arrays.copyOf(origin, 2*origin.length);
命令行参数
程序的主方法public static void main(String[[] args)接受的args数组包含了命令行参数
如在命令行执行:java className -g cruel world
则args数组中的参数为:{"-g","cruel","workd"}。