1.1 一个简单的Java应用程序
1 public class FirstSample { 2 public static void main(String[] args){ 3 System.out.println("hello Java"); 4 } 5 }
1.2 注释
单行注释://code
多行注释:/*code*/
文档注释:/**code*/
1.3 数据类型
Java中有八种基本数据类型:
- 4种整型(byte、short、int、long)
- 2种浮点型(float、double)
- 1中字符类型(char)
- 1中boolean类型(boolean)
类型 | 存储要求 | 取值范围 |
---|---|---|
byte | 1字节 | -128~127 |
short | 2字节 | -32768~32767 |
int | 4字节 | -2147483648~2147483647 |
long | 8字节 | -9223372036854775808~9223372036854775807 |
2种浮点型
类型 | 储存要求 | 取值范围 |
---|---|---|
float | 4字节 | 大约±3.40282347E±38F(有效数字为6~7位) |
double | 8字节 | 大约±1.79769313486231570E+308(有效位数为15位) |
1.4 变量
1.4.1 变量的声明
1 String name; 2 int age; 3 doublr weight;
可以在一行中声明多个变量:
1 String name,school,address;
1.4.2 变量的初始化
1 //方式一 2 String name = "小明"; 3 //方式二 4 String name; 5 name = "小明";
注意:变量名大小写敏感,变量的声明尽可能的靠近变量第一次使用的地方
1.4.3 常量
利用关键字final指示常量,如:
1 final int AGE = 10
关键字final表示这个变量只能被赋值一次。一旦被赋值之后,就不能够再更改了。习惯上,常量名使用全大写。
1.5 运算符
Java中使用+、-、*、/、%表示加、减、乘、除、求余运算
1.5.1 数学函数与常量
1 //算一个数值的平方根 2 Math.sqrt(x); 3 //幂运算 4 Math.pow(x,a); 5 //Math类提供了一些常用的三角函数 6 Math.sin(); 7 Math.cos(); 8 Math.tan(); 9 Math.atan(); 10 Math.atan2(); 11 //自然对数以及以10为底的对数 12 Math.exp(); 13 Math.log(); 14 Math.log10(); 15 //Java还提供了两个用于表示Π和e常量的近似值 16 Math.PI; 17 Math.E;
1.5.2 数值类型之间的转换
数值类型之间的合法转换如下图所示(其中虚线表示会丢失精度):
1.5.3 强制类型转换
在必要的时候,int类型的值将会自动地转换为double类型。但另一方面,有时也需要将double转换成int。在Java中,允许进行这种数值之间的类型转换。当然,有可能会丢失一些信息。在这种情况下,需要通过强制类型转换(cast)实现这个操作。强制类型转换的语法格式是在圆括号中给出想要转换的目标类型,后面紧跟待转换的变量名。例如:
1 double x = 9.997; 2 int nx = (int) x;
如果想对浮点数进行舍入运算,以便得到最接近的整数(在很多情况下,这种操作更有用),那就需要使用Math.round方法:
1 double x = 9.997; 2 int nx = (int)Math.round(x);
注意:如果试图将一个数值从一种类型强制转换为另一种类型,而又超出了目标类型的表示范围,结果就会截断成一个完全不同的值。
1.5.4 结合赋值和运算符
可以在赋值中使用二元运算符,这是一种很方便的简写形式。例如:
1 x+=4;
等价于:
1 x = x + 4;
1.5.5 自增与自减运算符
自增、自减运算符:n++将变量n的当前值加1,n--则将n的值减1。例如,以下代码:
1 int n = 12; 2 n++;
将n的值改为13。由于这些运算符会改变变量的值,所以它们的操作数不能是数值。例如,4++就不是一个合法的语句。
上面介绍的是运算符放在操作数后面的“后缀”形式。还有一种“前缀”形式:++n。后缀和前缀形式都会使变量值加1或减1。但用在表达式中时,二者就有区别了。前缀形式会先完成加1;而后缀形式会使用变量原来的值。
int m = 7; int n = 7; int a = 2 * ++m;//此时m是8,a是16 int b = 2 * n++;//此时n是8,b是14
1.6 字符串
每个用双引号括起来的字符串都是一个String的实例:
String empty = "";//这是一个空字符串 String greeting = "Hello";
1.6.1 字串
通过substring方法可以截取一个字符串的子串:
String greeting = "Hello"; String sub = greeting.substring(0,3);//字符串截取从0开始到2结束(不包含3);sub的截取结果为:“Hel”。
1.6.2 拼接
Java中的字符串可以通过+进行拼接:
String str1 = "Hel"; String str2 = "llo"; String str3 = str1+str2;//str3的结果为:“Hello”。
将一个字符串与一个非字符串进行拼接时后者将被转换为字符串(任何一个Java对象都可以被转换为字符串):
int age = 12; String str = "hello"+age;//str的值为:“hello12”。
如果需要把多个字符串放在一起,用一个定界符分隔,可以使用静态join方法:
String allSize = String.join("/","S","M","L","XL");//allSize的结果为:“S/M/L/XL”。
1.6.3 不可变字符串
String类没有提供用于修改字符串的方法。如果需要修改字符串首先提取需要的字符,然后再拼接上替换的字符串。由于不能修改Java字符串中的字符,所以在Java文档中将String类对象称为不可变字符串,如同数字3永远是数字3一样,字符串“Hello”永远包含字符H、e、l、l和o的代码单元序列,而不能修改其中的任何一个字符。当然,可以修改字符串变量,让它引用另外一个字符串,这就如同可以将存放3的数值变量改成存放4一样。
1.6.4 检测字符串是否相等
可以使用equals方法检测两个字符串是否相等:
String greeting = "hello"; boolean result = greeting.equals("hello");//如果两个字符串相等则返回true,不相等返回false;
要想检测两个字符串是否相等,而不区分大小写,可以使用方法:
"Hello".equalsIgnoreCase("hello");
一定不要使用==运算符检测两个字符串是否相等!这个运算符只能够确定两个字符串是否放置在同一个位置上。当然,如果字符串放置在同一个位置上,它们必然相等。但是,完全有可能将内容相同的多个字符串的拷贝放置在不同的位置上。如果虚拟机始终将相同的字符串共享,就可以使用==运算符检测是否相等。但实际上只有字符串常量是共享的,而+或substring等操作产生的结果并不是共享的。因此,千万不要使用==运算符测试字符串的相等性,以免在程序中出现糟糕的bug。从表面上看,这种bug很像随机产生的间歇性错误。
1.6.5 空串与Null串
空串“”是长度为0的字符串,可以用以下方法判断字符串是否是空串:
if(str.length ==0) //或者 if(str.equals(""))
要检查一个字符串是否为null,可以使用以下方法:
if(str == null)
要检查一个字符串既不是空串也不是null,可以使用以下方法:
if(str != null && str.length() != 0)
首先要检查str不为null,再检查长度是否为0,否则可能出现空指针异常。
1.6.6 构建字符串
如果需要用许多小段的字符串构建一个字符串,那么应该按照下列步骤进行。首先,构建一个空的字符串构建器:
StringBuilder builder = new StringBuilder();
当每次需要添加一部分内容时,就调用append方法:
builder.append('hel');
builder.append("lo");
在需要构建字符串时就调用toString方法,将可以得到一个String对象,其中包含了构建器中的字符序列:
String result = builder.toString();
在JDK5.0中引入StringBuilder类。这个类的前身是StringBuffer,其效率稍有些低,但允许采用多线程的方式执行添加或删除字符的操作。如果所有字符串在一个单线程中编辑(通常都是这样),则应该用StringBuilder替代它。
1.7 控制流程
1.7.1 条件语句
条件语句的格式为:
if(condition){ statement }else if(condition){ statement }else{ statement }
1.7.2 循环
while循环:
while(condition){ statement }
do...while循环:
do{ statement }while(condition);
for循环(确定循环):
for(int i = 0;i<100;i++){ statement }
foreach循环:
for(variable:collection){ statement } //例如 List<String> strList = new ArrayList(); for(String item:strList){ System.out.println(item); }
1.7.3 多重选择:switch语句
int choice = 1; switch(choice){ case 1 : ... break; case 2 : ... break; case 3 : ... break; case 4 : ... break; default: ... break; }
1.8 大数值
如果基本的整数和浮点数精度不能够满足需求,那么可以使用java.math包中的两个很有用的类:BigInteger和BigDecimal。这两个类可以处理包含任意长度数字序列的数值。BigInteger类实现了任意精度的整数运算,BigDecimal实现了任意精度的浮点数运算。使用静态的valueOf方法可以将普通的数值转换为大数值:
BigInteger bigNum = BigInteger.valueOf(100);
1.8.1 BigInteger(任意精度的整数运算)
得到一个大整数和另一个大整数other的和、差、积、商以及余数,分别用以下方法:
·BigInteger add(BigInteger other)
·BigInteger subtract(BigInteger other)
·BigInteger multiply(BigInteger other)
·BigInteger divide(BigInteger other)
·BigInteger mod(BigInteger other)
比较一个大整数与另一个大整数other的大小用compareTo方法,如果这个大整数与另一个大整数other相等,返回0;如果这个大整数小于另一个大整数other,返回负数;否则,返回正数:
·int compareTo(BigInteger other
获取一个数值的大整数值:
·static BigInteger valueOf(long x)
1.8.2 BigDecimal(任意精度的浮点数运算)
得到一个大实数和另一个大实数other的和、差、积、商,分别用以下方法,要想计算商,必须给出舍入方式(rounding mode):
·BigDecimal add(BigDecimal other)
·BigDecimal subtract(BigDecimal other)
·BigDecimal multiply(BigDecimal other)
·BigDecimal divide(BigDecimal other,RoundingMode mode)
比较一个大实数与另一个大实数other的大小用compareTo方法,如果这个大实数与另一个大实数other相等,返回0;如果这个大实数小于另一个大实数other,返回负数;否则,返回正数:
·int compareTo(BigDecimal other)
返回值为x或x/10scale的一个大实数:
·static BigDecimal valueOf(long x) ·static BigDecimal valueOf(long x,int scale)
1.9 数组
数组是一种数据结构,用来存储同一类型值的集合,通过一个整型下标可以访问数组中的每一个值。
数组的声明与初始化:
int[] a; //或者 int a[]; //数组的初始化 int[] a = new int[100];//声明了一个长度为100的整数数组
注意:
1、数组的下标是从0开始的而不是从1开始的;
2、创建一个数字类型的数组时,所有的元素都会初始化为0;创建一个Boolean类型的数组时,所有的元素都会初始化为false;创建一个对象类数组时,所有的元素都会初始化为null;
3、如果创建了一个长度为100的数组a,试图访问a[100],则会出现索引越界的异常;
4、数组一旦创建,就不能改变它的大小了(可以改变每个元素的值);如果需要经常在运行的过程中扩展数组的大小,则需要使用另一种数据结构---集合。
1.9.1 数组的初始化以及匿名数组
Java中提供了一种创建数组对象并同时赋予初始化值的简化书写形式:
int[] numArr = {1,2,3,4,5};//使用这种语法时不需要调用new
初始化一个匿名数组:
new int[]{1,2,3,4,5};//这种表示法将创建一个新数组并利用括号中提供的值进行初始化,数组的大小就是初始值的个数。使用这种语法形式可以在不创建新变量的情况下重新初始化一个数组。 //例如: numArr = new int[]{1,2,3,4,5,6,7};
1.9.2 数组的拷贝
数组的拷贝使用Arrays类的copyOf方法:
int[] copyNumArr = Arrays.copyOf(numArr,numArr.lenth); //第二个参数表示数组的长度
通常使用第二个参数来增加数组的大小:
int[] copyNumArr = Arrays.copyOf(numArr,2 * numArr.lenth);
如果数组元素是数值型,那么多余的元素将被赋值为0;如果数组元素是布尔型,则将赋值为false。相反,如果长度小于原始数组的长度,则只拷贝最前面的数据元素。
1.9.3 数组的排序
想要对数值类型的数组进行排序,可以使用Arrays类的sort方法:
int[] arr = new int[100]; arr = {1,4,8,5,4,2}; Arrays.sort(arr);
1.9.4 Arrays类中常用的API
·static String toString(type[] a)
返回包含a中数据元素的字符串,这些数据元素被放在括号内,并用逗号分隔。
参数:a类型为int、long、short、char、byte、boolean、float或double的数组。
·static type copyOf(type[] a,int length)
·static type copyOfRange(type[] a,int start,int end)
返回与a类型相同的一个数组,其长度为length或者end-start,数组元素为a的值。
参数:a 类型为int、long、short、char、byte、boolean、float或double的数组。
start 起始下标(包含这个值)。
end 终止下标(不包含这个值)。这个值可能大于a.length。在这种情况下,结果为0或false。
length 拷贝的数据元素长度。如果length值大于a.length,结果为0或false;否则,数组中只有前面length个数据元素的拷贝值。
·static void sort(type[] a)
采用优化的快速排序算法对数组进行排序。
参数:a 类型为int、long、short、char、byte、boolean、float或double的数组。
·static int binarySearch(type[] a,type v)
·static int binarySearch(type[] a,int start,int end,type v)
采用二分搜索算法查找值v。如果查找成功,则返回相应的下标值;否则,返回一个负数值r。-r-1是为保持a有序v应插入的位置。
参数:a 类型为int、long、short、char、byte、boolean、float或double的有序数组。
start 起始下标(包含这个值)。
end 终止下标(不包含这个值)。
v 同a的数据元素类型相同的值。
·static void fill(type[] a,type v)
将数组的所有数据元素值设置为v。
参数:a 类型为int、long、short、char、byte、boolean、float或double的数组。
v 与a数据元素类型相同的一个值。
·static boolean equals(type[] a,type[] b)
如果两个数组大小相同,并且下标相同的元素都对应相等,返回true。
参数:a、b 类型为int、long、short、char、byte、boolean、float或double的两个数组。
1.9.5 多维数组
二维数组的声明:
int[][] arr;
二维数组的初始化:
arr = new int[3][4];
如果知道数组的元素,就可以不调用new,使用简化的书写方式对二维数组进行初始化:
int[][] arr = { {1,2,3,4}, {5,6,7,8}, {2,4,5,6}, {6,4,2,6} };
想要快速的打印二维数组的元素列表,可以使用Arrays类的deepToString方法 :
System.out.println(Arrays.deepToString(arr)); //输出结果格式为:[[1,2,3],[14,5,6],[7,8,9]]