1.一个简单的java应用程序
1 public class FirstSample {
2
3 public static void main(String[] args) {
4 // TODO Auto-generated method stub
5 System.out.println("hello world");
6 }
7
8 }
View Code
虽然这是一个简单的java程序,但是所有的java应用程序都具有这种结构
需要注意的是:
首先java是区别大小写的,如果出现大小写问题那么程序将无法运行
java应用程序中的所有内容必须都放置在类中
java中定义类名的规则很宽松:名字必须以字母开头,后面可以跟字母和数字的任意组合,长度没有限制,但是不能用java保留字作为类名
标准的命名方法(驼峰命名法):就是首字母大写,如果多个字母组成,那么每个单词的首字母都应该大写,像驼峰一样。
源代码的名字必须和公共类的名字相同,并且以.java作为扩展名。
JVM运行.class文件时,首先从main方法开始
在java中,用大括号划分程序的各个部分(通常叫做块),java中任何方法的代码都用“{”开始用“}”结束
在java中,每个句子必须要用分号结束,特别需要说明,回车不是语句的结束标志,因此,如果需要,可以把一条语句写在多行
在这样System.out.println("hello world");使用了System.out对象并且调用了它的方法println,注意点好(.)用于调用方法
,java使用的通用语法是object.method(参数)。
2.注释
最常用的注释是//:其注释内容用//开始到本行结尾
当需要长篇的注释时,可以用多行//,也可以用/*------*/把它括起来
第三种注释:用来自动生成文档,/**--------*/
3.数据类型
java是一种强类型语言,这就意味者要为每一个变量声明一种类型
java中一共有8种基本类型,其中有4种整型,2种浮点型,1种用于表示Unicode编码的字符单元的字符类型char和一种表示真值的boolean类型
3.1 整型
整型:用于表示没有小数部分的数值,它允许是负数
4种整型分别是byte(1字节),short(2字节),int(4字节),long(8字节),一个字节8位二进制。
长整型后面有一个后缀L或者l(10L),十六进制前面会有一个前缀0x后者0X(0xCAFE),八进制有一个前缀0,从java7开始,加上前缀0b或者0B就可以表示二进制数。
3.2 浮点型
浮点类型表示有小数部分的数值。有float(4字节)和double(8字节)
double表示这种类型的数值进度是float的两倍(有人叫它双精度),绝大数情况下使用double,在很多情况下,float类型很难满足精度要求
float类型的数值后面会有一个F或者f(3.14F)。没有f或者F的浮点值默认为double类型。当然也可以在后面加上后缀D或者d
3.3 char类型
char类型的字面量要用单引号(‘’)括起来,只能放单字符
char类型是可以运算的,因为char在ASCII等字符编码表中有对应的数值,在java中进行char类型的运算的时候,直接当作ASCII码表中对应的整数来运算。
我们强烈建议不要在程序种使用char类型,除非要处理UTF-16代码单元,最好将字符串作为抽象数据类型处理
3.4 boolean类型
布尔类型:就两个值true和false用来判断逻辑判断
3.5 变量
变量名必须是一个以字母开头并由字母或数字组成的序列,可以在一行声明多个变量,但是不提倡,逐一声明每个变量可以提高程序的可读性。
声明变量后就要初始化,千万不能使用未初始化的变量
3.6 常量
在java中,利用关键字final指示常量,关键字final表示这个变量只能被赋值一次,一但被赋值,就不能修改了习惯上,常量名使用全大写。
在java中经常希望某个常量在一个类的多个方法中使用,通常将这些常量称为类常量,可以用final static设置一个类常量
3.7 运算符
在java中+,-,*,/表示加,减,乘,除。当参加/运算的两个数都是整数时,就叫整数除法,否则就是浮点数除法。
整数求余操作用%表示,有时叫做取模运算,需要注意:整数除0会出现异常,而浮点数除0会出现无穷大或者NAN结果
3.8 数学函数和常量
在Math中包含着各种各样的数学函数,我们编写函数时,可能要用到。在api说明文档中我们可以知道,Math类在java.lang
中所以不要导包就可以用,使用方式就是Math.method();
求平方根可以用sqrt()
double a = 4;
double b = Math.sqrt(a);
System.out.println(b);
View Code
因为在java中没有幂函数所以我们可以用pow()方法
double c = Math.pow(2, 2);
System.out.println(c);
pow()方法有2个double类型的参数,返回值也是double
floorMod方法的目的则是解决一个长期存在的有关整数取余的问题
书上说的难懂,只能知道怎么取值
int m = Math.floorMod(15, 13);
System.out.println(m);//2
int n = Math.floorMod(-15, 13);
System.out.println(n);//11
int j = Math.floorMod(15, -13);
System.out.println(j);//-11
int k = Math.floorMod(-15, -13);
System.out.println(k);//-2
为什么会出现这样的情况呢https://blog.51cto.com/11604910/2372141可以参考这4张图
3.8 数值之间的合法转化
这种情况大多出现在 不同类型数值之间经行运算的时候
总结一下:就是从小数值类型转化为大的是合法的,不会有信息丢失,其中int-》float,long-》float,long-》double,可能会有精度损失,但是也是合法的
总结以下就是:如果2个数中有一个是double,另外一个就会转化为double
否则,其中一个是float,另外一个就会转化为float
否则,其中一个是long,另外一个就会转化为long
否则,两个都会被转化为int类型
3.9 数值之间的强制转化
也就是上面相反的转化,从大到小,但是有可能会丢失信息,但是java允许这种转化,但是要在前面加上要转化的数据类型,并且用括号()括起来
1 double x = 3.14;
2 int y = (int)x;
3 System.out.println(y);//3
正如上面说的会丢失信息。
如果想对一个浮点数进行四舍五入,以便获得最接近的整数,那就需要用到Math.round()方法
1 double m = 3.45;
2 double n = 3.55;
3 long a = Math.round(m);
4 long b = Math.round(n);
5 System.out.println(a);//3
6 System.out.println(b);//4
4.0 结合赋值和运算符
a+=b等价于a = a + b
其他的运算符也有这样的表示
4.1 自增和自减运算符
++和--
n++表示n+1
n--表示n-1
其实还有一种表达方式就是++n,也是表示n+1,但是在表达式中就不是这样了
在表达式中n++;先将n带进去运算后n+1
++n而是先将n+1,把n+1带进去运算,所以建议捕要在表达式中使用++,会使人产生困惑
下面是例子
int a = 20;
int c = 10;
int e = 10;
int b;
int d;
b = a * c++;//c=11
d = a * ++e;//e=11
System.out.println(b);//200
System.out.println(d);//220
View Code
4.2 关系和boolean运算符
java有丰富的关系运算符,要检查是否相等可以用==,检查不相等可以用!=
还经常用<,>,>=,<=;
java还沿用了c++的逻辑与&&,逻辑或||,逻辑非!。
&&和||是通过短路的方法来求值的,那么何为短路方法呢,我们先用&&来说明 message1&&message2,如果message1是false,那么不管message2为true还是false,结果都是false,所以我们没必要判断message2,也就是不必计算message1这个表达式。||也是这个意思。这就是所谓的短路。
4.3 三元操作符
codition?a:b意思很简单就是如果codition为true则执行a,为false则执行b。
4.4 位运算符
位运算符有与(&),或(|),非(~),异或(^)
表明看起来位运算符和&&和||好像差不多,但是操作对象不一样,位运算符是对两个二进制数进行操作,而boolean运算符是对两个关系运算符进行操作
与(&);如果都为1,则为1,其他情况都为0
或(|);如果有一个为1,则为1,其他情况都为0
非(~);如果位为1,结果为0,位为0,结果为1
异或(^);如果两位相同则为0,不同则为1
左移运算符(<<);低位补0
有符号右移(>>);为负则前面全部补1,为正则后面全部补0
无符号右移(>>>);无论是正还是负,高位都补0
4.5 括号与运算符级别
如果有圆括号则先计算圆括号里面的,没有的话,就根据给出的运算符优先级次序进行计算,同一级别按从左到右计算(除了一些右结合运算符外)这些运算符优先级次序网上都有,这里就不一一给出
4.6 字符串
从概念上讲,Java字符串就是Unicode字符序列。java没有内置的字符串类型,而是在标准java类库中提供了一个预定义类,很自然的叫做String,每个用“”括起来的字符串都是String类的实例
4.61 子串
String类的substring方法可以从一个较大的字符串中提取出一个子串,下面是例子
String s = "yangfan";
String b = s.substring(0,4);
System.out.println(b);//yang
这方法需要注意的是后面的位取不到,以上面的例子来说就是4位取不到,只取到0-3的字符串
这个方法有个优点就是:很容易知道子串的长度,substring(a,b),length=b-a;
4.62 拼接
与绝多数的程序设计语言一样,java允许用+来拼接两个字符串
当一个字符串和一个非字符串拼接时,后者会被转化成字符串(后面我们可以知道,任何一个java对象都可以转化成字符串)
如果我们需要把多个字符串放在一起,而且用一个定界符分隔,可以使用静态join方法,以下就是例子
String all = String.join("?", "a","b","c");
System.out.println(all);//a?b?c
4.63 不可变字符串
java字符串中的字符是不能修改的,举个例子String s = “hello”,字符串“hello”里面的任何一个字符都不能被修改,当然字符串变量s可以变,可以指向别的字符串
不可变字符串在修改字符串上可能效率低,但是不可变字符串有个优点:编译器可以让字符串共享。
总而言之,java设计者认为共享带来的高效率远远胜于提取和拼接字符串带来的低效率。
4.64 检测字符串是否相等
这里需要说一下==与equals()方法
==:比较的是引用是否相等,也就是说两个变量是否指向同一地址
而equals()方法:api中也是比较引用是否指向同一地址,但是String类重写了这个类,使得equals()比较的是字符串的值是否相等,也就是内容是否相同!下面为例子
1 String a = new String("YF");
2 String b = new String("YF");
3 System.out.println(a == b);//false
4 System.out.println(a.equals(b));//true
5 String c = "YF";
6 String d = "YF";
7 System.out.println(c == d);//true
8 System.out.println(c.equals(d));//true
View Code
如果需要比较两个字符串忽视大小写是否相等就可以用,equalsIgnoreCase()
如果虚拟机始终将相同的字符串共享,就可以用==运算符检查是否相同,但是注意!!!只有字符串常量是共享的,而+和substring等操作的结果并不是共享的,因此千万不要用==来比较两个字符串内容是否相等!
下面例子
String a = new String("YF");
String b = new String("YF");
String c = "YF";
String d = "YF";
String e = "YFYF";
String x = a + b;
String y = c + d;
System.out.println(e==x);//false
System.out.println(e==y);//false
System.out.println(x==y);//false
总之我们记住一个结论就是:只有字符串常量是共享的,其他都是形成新的字符串,而不是共享
4.65 空串和Null
空串是“”字符串长度为0的字符串,可以用下面两种方法来检查一个字符串是否为空字符串
String s = "";
System.out.println(s.equals(""));//true
System.out.println(s.length()==0);//true
空串是一个java对象,有自己的长度(0)和内容(空),String变量还可以存放一个特殊的值,名为null,这表示这个变量目前和任何对象都没有关联。可以用以下方法检测一个字符串是否是null
String s = null;
System.out.println(s == null);//true
如果需要检查一个字符串既不是null也不是空串,需要使用下面的条件
if(str != null && str != "")
首先要检查str不为null
4.46 码点与代码单元
这个部分讲到了编码原理,比较深入,不适合目前的java学习,故暂不学习
4.47 构建字符串
有时候需要由较短的字符串构建字符串,而使用字符串拼接的方法达到此目的效率比较低,每次连接字符串,都会构建一个新的字符串,即耗时,又浪费空间。使用StringBuilder类就可以避免这个问题。
使用方法如下:
1 StringBuilder sb = new StringBuilder();
2 sb.append("hello ");
3 sb.append("world!");
4 String s = sb.toString();
5 System.out.println(s);
View Code
5 输入输出
前面我们知道打印输出“标准输出流”是一件十分简单的事,只要调用System.out.println();即可,然而读取“标准输入流”就没有这么简单了,要想通过控制台进行输入,首先要构建一个Scanner对象,并与“标准输入流”System.in关联
Scanner in = new Scanner(System.in);
我们用一个例子来说明,要注意的是,因为Scanner类定义在java.util包中,当使用的类不是定义在java.lang包中时,需要进行导包操作,下面是例子
1 Scanner in = new Scanner(System.in);
2 System.out.println("你的名字是?");
3 String name = in.nextLine();
4 System.out.println("你今年多大?");
5 int age = in.nextInt();
6 System.out.println("你的名字是:"+name+",你今年"+age+"岁");
7 in.close();
View Code
需要了解的是nextLine()读取的是下一行的内容,nextInt()方法则是读取下一个数字
5.1.1 格式化输出
从javaSE5.0开始沿用了c语言的printf方法
每个以%字符开始的格式说明符都用相应的参数替换,格式说明符尾部的转化符将指示被格式化的数值类型,f代表浮点数,s代表字符串,d代表十进制。完整的转换符网上都有,不一一列出。另外还有可以控制格式化输出的各种标志,这里也不一一列出。
还可以使用静态方法String.format()方法创建一个格式化的字符串,而不打印。
1 String name = "java";
2 String s = String.format("hello,%s!", name);
3 System.out.println(s);
View Code
书上还介绍了关于printf方法中日期与时间的格式化选项,格式包括2个字符,以t开始后面加上合适的另外一个字母,下面是例子
1 //星期三 四月 10 10:58:30 CST 2019
2 System.out.printf("%tc", new Date());
3 System.out.println();
View Code
但是,我们从表中可以看到,很多格式只给出指定日期的部分信息。代码如下
System.out.printf("%tB", new Date());
//四月
System.out.println();
System.out.printf("%te", new Date());
//10
System.out.println();
//2019
System.out.printf("%tY", new Date());
View Code
这样会导致需要多次对日期操作才能实现对每一部分进行格式化。这样就会很麻烦。为此我们采用一个格式化的字符串指出要被格式化的参数索引,索引必须紧跟在%后面并且以$结尾,也可以用<标志,它指示前面的格式说明中的参数被再次使用
用例子来说明
1 //星期三 四月 10 10:58:30 CST 2019
2 System.out.printf("%s %tB %te %tY","Due date",new Date(),new Date(),new Date());
3 System.out.println();
4 System.out.printf("%1$s,%2$tB,%2$te,%2$tY","Due date",new Date());
5 System.out.println();
6 System.out.printf("%s,%tB,%<te,%<tY","Due date",new Date());
View Code
输出的效果是一模一样的
5.2 文件的输入与输出
如果想要对文件进行读取,并且在控制台显示它们,就需要用File对象构造一个Scanner对象,如下面例子
//hello World!
Scanner in = new Scanner(Paths.get("D://project//yf.txt"),"UTF-8");
String s = in.nextLine();
System.out.println(s);
in.close();
View Code
现在就可以用前面介绍的任何Scanner方法来对文件进行读取
如果想要写入文件,就需要构造一个PrintWirite对象,并在构造器中,提供文件名!如果文件不存在则会创建该文件
然后像System.out一样使用println等方法写入,例子如下
PrintWriter out = new PrintWriter("D://project//yf2.txt","UTF-8");
out.println("hello world!");
out.close();
View Code
6.1 控制流程
首先介绍块的概念:块(即复合语句)是指由一对大括号括起来的若干简单的java语句。块决定了变量的作用域。
一个块可以嵌套在另一个块中。但是不能在嵌套的两个块中声明同名变量
6.2 条件语句
分if 和 if else 简单不做说明
6.3 循环
分while();循环 true则一直运行下去
do{}while();它至少做一次
for();是支持迭代的一种通用结构,每次迭代后更新计数器或类似的变量来控制迭代次数。与c++一样。尽管java允许在for循环的各个部分放置任何表达式,但是有一条不成文的规则:for语句的3个部分应该对同一个计数器变量进行初始化,检测,更新。若不守规则,编写的循环常常难以理解。for循环只不过是while循环的一种简化形式
关于for循环还有注意的是:如果在for语句中定义一个变量,那么在循环体外这个变量就不能使用,如果希望在for循环外使用循环计数器的最终值,那么应该确保这个变量在循环语句外声明。
6.4 switch语句
1 switch(choice){
2 case 1:
3 . . .
4 break;
5 case 2:
6 . . .
7 break;
8
9 case 3:
10 . . .
11 break;
12
13 case 4:
14 . . .
15 break;
16 default:
17 . . .
18 break;
19 }
switch语句将从与选项值相匹配的case标签开始执行,直到遇到break语句,或者执行到switch语句的结束处为止。
如果没有相匹配的case标签,而又default子句,那么执行这个子句。
case标签可以是,char,byte,short,int的常量表达式,枚举常量,从SE7开始可以是字符串字面量。
6.5 中断控制流程语句
break,continue,还有带标签的break和continue。
break就是跳出循环,continue则是跳出这次循环。很好理解
而带有标签的break的意思就是,跳出带有标签的这个循环,我们用一个例子说明
1 for(){
2 me:
3 for(){
4 for(){
5 ...
6 for(){
7 break me;
8 }
9 }
10 }
11 }
View Code
这个例子中的意思就是,跳出带有me标签的这个循环。continue带标签也是这个用法。
6.6 对大数值的处理
如果基本的整数和浮点数精度不能满足需求的话,可以使用java.math包中的两个很有用的类:BigInteger和BigDecimal。
这两个类可以处理包含任意长度数字序列的数值。BigInteger类实现了任意精度的整数运算,BigDecimal类实现了任意精度的浮点数运算。可以使用静态的valueOf()将普通数值转化为大数值。
BigInteger a = BigInteger.valueOf(100);
遗憾的是,不能使用熟悉的+,*,来处理大数值,而是用方法add()和multiply()
BigInteger a = BigInteger.valueOf(100);
BigInteger b = a.add(a);
BigInteger c = a.multiply(a);
System.out.println(b);//200
System.out.println(c);//10000
7 数组
首先需要明确的是:数组是一种数据结构,用来储存同一类型值得集合,可以通过一个整型下标来访问数组中每一个值。
创建一个数字数组时,所有元素都初始化为0,boolean数组得元素会初始化为false,对象类型会初始化为null。还要注意一点,一旦创建了数组,它们得大小就确定了,不能修改它的大小(尽管可以修改每一个元素)。如果经常需要在运行过程中扩展数组的大小,就应该用另外一种数据结构-数组列表(array list)。
7.1 for each循环
java有一种功能很强大的循环结构,可以用来依次处理数组中的每个元素(其他类型的元素集合亦可)而不必为指定下标而分心。
for(variable : collection) statement
7.2 数组初始化以及匿名数组
java中,提供了一种创建数组对象并同时赋予初始化值的简化书写形式。
int[] a = {1,2,3,4,5};
甚至可以初始化一个匿名的数组
new int[] {1,2,3,4,5};
使用这种语法形式可以在不创建新变量的情况下重新初始化一个数组。
7.3 数组拷贝
在Java中允许将一个数组变量拷贝给另一个数组变量,这时,两个变量将引用同一个数组。
如果希望一个数组的所有值都拷贝到另一个新的数组中去,就要用到Array类中的copyof方法,例子如下
int[] a = {1,2,3,4,5};
int[] b = Arrays.copyOf(a,a.length);
for(int i : b){
System.out.println(i);
}
View Code
如果后面的参数大于原数组的长度,如果数组元素时数值型,就补0,boolean就补false,相反如果小于原数组的长度,那么就赋值前面的元素。
7.4 数组排序
要想对数组型数组进行排序,可以用Arrays类中的sort方法,这个方法使用了优化的快速排序算法。快速排序算法对于大多数数据集合来说都是效率比较高的。例子
int[] a = {1,20,3,0,0,10};
Arrays.sort(a);
for(int i : a){
System.out.print(i+" ");
}
输出为:0 0 1 3 10 20
7.5 多维数组
二数组:其实就是一维数组里面的元素都是一维数组。
int[][] a = new int[][];
int[][] a = {
{},
{},
};
java实际上没有多维数组,只有一维数组。多维数组被解释为“数组的数组”。
还有一个不规则数组的概念,就是数组的数组,但是它们的长度不一样。
8 命令行参数
我们这里来讲讲main(String[] args)中的args,这表示main方法将接受一个字符串数组,也就是命令行参数
1 public class Hello {
2
3 public static void main(String[] args) {
4 // TODO Auto-generated method stub
5 for(String s : args){
6 System.out.println(s);
7 }
8 }
9
10 }
结果是这样的
。这就可以说明args字符串变量存储的就是
命令行参数。