1.Java入门



1.1java概述


Java的三种技术架构:

JAVAEE:JavaPlatform Enterprise Edition,开发企业环境下的应用程序,主要针对web程序开发;

JAVASE:JavaPlatform Standard Edition,完成桌面应用程序的开发,是其它两者的基础;

JAVAME:JavaPlatform Micro Edition,开发电子消费产品和嵌入式设备,如手机中的程序;


1.2 Dos命令行


dir:列出当前目录下的文件以及文件夹

md:创建目录

rd:删除目录

cd:进入指定目录

cd..:退回到上一级目录

cd/:退回到根目录

del:删除文件

exit:退出dos命令行

 

在dos界面内删除文件夹,必须先保证文件夹是空的,可以利用

del 文件夹名      来删除文件夹内的文件

rd  文件夹名      来删除文件夹

 

del *.txt 表示删除文件夹下所有txt后缀的文件

 

 

1.3 java跨平台性


可以通过Java虚拟机(JVM)在系统当中运行,不同系统有不同版本的虚拟机,但java程序不用改变

 

 

1.4 Java语言的环境搭建


JRE:Java RuntimeEnvironment,java程序的运行环境,java运行的所需的类库+JVM(java虚拟机)。

JDK:Java Development Kit,java的开发和运行环境,java的开发工具和jre。

 

配置环境变量:让java jdk\bin目录下的工具,可以在任意目录下运行,原因是,将该工具所在目录告诉了系统,当使用该工具时,由系统帮我们去找指定的目录。

永久配置环境变量方式:

定义java_home的值,利用%java_home%即可动态提取java_home的值,则当java程序目录改变时,只需要变更java_home的值就可以更改环境变量

如下:JAVA_HOME=%安装路径%\Java\jdk

      path=%JAVA_HOME%\bin

 

临时配置环境变量方式:

通过dos命令set,set path就可以看到环境变量path的值,set path= 即可临时定义path的值。如果通过start开启命令符,会继承临时配置的环境变量

特点:系统默认先去当前路径下找要执行的程序,如果没有,再去path中设置的路径下找。

如下:set path=%path%;C:\ProgramFiles\Java\jdk\bin

 

classpath的配置:

永久配置方式:classpath=.;c:\;e:\

临时配置方式:set classpath=.;c:\;e:\

注意:在定义classpath环境变量时,需要注意的情况

如果没有定义环境变量classpath,java启动jvm后,会在当前目录下查找要运行的类文件;

如果指定了classpath,那么会在指定的目录下查找要运行的类文件。

还会在当前目录找吗?两种情况:

    1):如果classpath的值结尾处有分号,在具体路径中没有找到运行的类,会默认在当前目录再找一次。

    2):如果classpath的值结尾处没有分号,在具体的路径中没有找到运行的类,不会再当前目录找。

    一般不指定分号,如果没有在指定目录下找到要运行的类文件,就报错,这样可以调试程序。

 

 

1.5 Java程序开发体验

 

javac命令,负责的是编译的部分,当执行javac时,会启动java的编译器程序。对指定扩展名的.java文件进行编译。 生成了jvm可以识别的字节码文件。也就是class文件,也就是java的运行程序。

java命令,负责运行的部分.会启动jvm加载运行时所需的类库,并对class文件进行执行。

 

可以通过set classpath=类所在目录,来临时设置类环境变量,这样可以在任意文件夹中调用编写的类文件,在配置classpath时,结尾不加“;”,加上“;”表示会在目标路径和当前路径下进行寻找

Classpath=.;c:\;d:\   ( . 表示在当前文件夹下寻找)

 

通过java运行的class文件,优先执行的是环境变量中设置的,比当前文件夹下的类文件更加优先

 

class 用于定义类,类名通常由单词组成,每个单词首字母大写。用 { }表示类区间

 

public static voidmain(String[] args)   为固定形式的主函数,其作用在于保证类独立运行

一个文件要被执行,必须要有一个执行的起始点,这个起始点就是main函数

 

//   单行注释;

 

/*  

*/   多行注释;

 

/**

*/   文档注释;

 

注释符也可用于程序调试,多行注释中不能插入多行注释



2.Java语言基础组成



2.1关键字


其实就是某种语言赋予了特殊含义的单词。像:this、super、class等,关键字都是小写。

 

2.2 标识符

 

Java中的包、类、方法、参数和变量的名字,由任意顺序26个英文字母大小写,数字0-9,符号_$组成,数字不可以开头,不可以使用关键字

16进制需以0x开头

 

负数的二进制表现形式,就是将正的二进制取反+1,取反即1变0,0变1。负数的最高位都是1。

 

2.3 变量


变量就是内存中的一个存储空间,用于存储常量数据。

作用:方便于运算。因为有些数据不确定。所以确定该数据的名词和存储空间。

特点:变量空间可以重复使用。

只要数据不确定的时候,就定义变量变量空间的开辟需要的要素有:数据类型、变量名称、变量初始化值。

 

变量的作用域和生存期:

变量的作用域:

   作用域从变量定义的位置开始,到该变量所在的那对大括号结束;

生命周期:

   变量从定义的位置开始就在内存中活了;

   变量到达它所在的作用域的时候就在内存中消失了;

 

数据类型:

1)基本数据类型

数值型:整数类型 byte  8  个二进制位表示 -128~127

                 short  16 个二进制位表示

                 int    32 个二进制位表示             默认整数类型为这个

                 long   64 个二进制位表示

        浮点类型 float  单精度                         定义时需在数字后面加上f

       (即小数)double 双精度                         默认形式

字符型: char

2)引用数据类型:数组、类、接口

 

2.4 类型转换

级别从低到高为:byte,char,short(这三个平级)-->int-->float-->long-->double

自动类型转换:从低级别到高级别,系统自动转的;

强制类型转换:什么情况下使用?把一个高级别的数赋给一个别该数的级别低的变量;

 

byte b =3

b = b +2                   将会报错,2默认类型为int,不同类型不能运算

b =(byte) (b + 2)             通过强制转换即可

 

‘a’+1                      其值为98,因为此时会将字符a提升为int型(即97)

 

字符串数据和任何数据使用+都是相连接,最终都会变成字符串

 

2.5 算术运算符


%为取模,如1%5=1,5%5=0,6%5=1,-1%5=-1,1%-5=1,正负只取决于左边的数

任何整数模2不是0就是1,所以只要改变被模数就可以实现开关运算。

 

++为自加,a++ 即 a=a+1

 

                   int a = 3,b;

                   b=a++;                           

                   System.out.println(b);                → 3

                   System.out.println(a);                → 4

        此运算为先将b赋于a的值,a再进行自加

 

 

2.6 转义字符

 

通过\来转变后面字母或符合的含义

\n:换行

\b:退格,相当于backspace

\r:按下回车键,window系统中,回车符是由两个字符来表示\r\n

\t:制表符,相当于tab键

 

System.out.println("\”Hello\”");    即可输出带”Hello”

 

 

2.7  赋值运算符


=  += -= *= /= %=


shorts=4;

s =s+5                             

上述运算将会报错,因为5为int型,将s+5赋值于s为不同类型的赋值,容易丢失精度

 

shorts=4;

s+=5

+=属于一个赋值动作,将会自动进行类型转换,因此此运算通过

 

 

2.8 逻辑运算符


and → &   两边有一个为false,结果为false

or  → |   两边有一个为true,结果为true

异或 → ^   和|有一些不一样,即true ^ true = false,两边相同,结果为false,两边不同,

结果为true

&&→ (and)短路  当左边为false,右边不运算,结果为false。

||  → (or)短路   当左边为true时,右边不运算,结果为true

 

 

2.9 位运算符


<< 左移 3<<2即先将3转换为二进制,再将位数左移,其值为12,3*2*2

>> 右移 6>>2即先将6转换为二进制,再将位数右移,其值为1,6/2/2

>>>无符号右移,>>的最高位如果是1需要补1,而>>>都是补0

&  如6&3,将6和3都转换成二进制,将两者各位进行 & 逻辑运算

|   将两者转换成二进制,再对各位进行 | 逻辑运算

^   将两者转换成二进制,再对各位进行 ^ 逻辑运算,即取反

 

将n与m的值进行交换,不通过第三方变量

int n = 3,m = 8;

n = n ^ m;

m = n ^ m;  // (n ^ m)^m

n = n ^ m;  //  (n^m)^n

 

 

2.10 三元运算符


(条件表达式)?表达式1:表达式2;

如果条件为true,运算后的结果是表达式1;

如果条件为false,运算后的结果是表达式2;

 

好处:可以简化if else代码

弊端:因为是一个运算符,所以运算完必须要有一个结果

 

 

将给定数字转换为16进制:

                   int num = 60;

                   int n1 = mun & 15;                         //提取num二进制的后四位

 

n1>9?(char)(n1-10+'A'):n1);  //输出提取数字的十六进制形式

 /*此处输出结果为67,因为n1为int型,三元运算时会将char型提升为int型*/

                   int temp = 60 >>> 4;                        //去除num二进制的后四位

                   int n2 = temp & 15;                         //提取第二个四位

 

                   System.out.println(n2>9?(char)(n2-10+'A'):n2);


2.11 程序流程控制


1) 判断结构


if else 结构 简写格式: 变量 = (条件表达式)?表达式1:表达式2;


//判断给定数字所属季节:
		int x = 4;
		if (x>12 || x<1)                          //先将无效的数字排除 
			System.out.println(x+"月份不存在");
		else if (x>=3 && x<=5)
			System.out.println(x+"春季");
		else if (x>=6 && x<=8)
			System.out.println(x+"夏季");
		else if (x>=9 && x<=11)
			System.out.println(x+"秋季");
		else
			System.out.println(x+"冬季");



2) 选择结构


switch语句

switch(表达式)
{
	case 取值1:
		执行语句;
		break;
	case 取值2:
		执行语句;
		break;
	 ……
	default:
		执行语句;
		break;
}



switch的值只包括byte, short ,int,char。case和default的排放顺序随意,但执行顺序是固定的,最后执行default

 

在switch语句中,String的比较用的是String.equals,因此可以放心的使用。

需要注意的是,传给switch的String变量不能为null,同时switch的case子句中使用的字符串也不能为null。

如果switch传入的null,那么在运行时对一个null对象调用hashCode方法会出现NullPointerException。

如果switch的case写的是null,那么在编译时无法求出hashCode,因此在编译时就会报错了。

 

switch的工作原理:用小括号中的变量的值依次和case后面的值进行对比,和哪个case后面的值相同了,就执行哪个case后面的语句,如果没有相同的则执行default后面的语句;

细节:1):break是可以省略的,如果省略了就一直执行到遇到break为止;

switch后面的小括号中的变量应该是byte,char,short,int四种类型中的一种;

            3):default可以写在switch结构中的任意位置;如果将default语句放在了第一行,则不管expression与case中的value是否匹配,程序会从default开始执行直到第一个break出现。

 

//判断给定数字所属季节:
		switch(x)
		{
			case 3:
			case 4:
			case 5:
				System.out.println(x+"春季");
				break;
			case 6:
			case 7:
			case 8:
				System.out.println(x+"夏季");
				break;
			case 9:
			case 10:
			case 11:
				System.out.println(x+"秋季");
				break;
			case 12:
			case 1:
			case 2:
				System.out.println(x+"冬季");
				break;
			default:
				System.out.println("none");
		}



if结构不仅能够判断数值,还能判断区间,而switch结构不好判断区间,而且不能判断boolean型

 

对于数值确定且不多,且符合byte short int char四种类型宜用switch结构,其他结构宜用if结构



3) 循环结构


1.dowhile 循环

do

{

    执行语句;

}

while (表达式);

 

while语句:先判断条件,只有条件满足才执行循环体

do while语句:先执行循环体,再判断条件,条件满足,再继续执行循环体。无论条件是否满足,循环体至少执行一次

 

 

2.for循环

for(初始化表达式;循环条件表达式;循环后的操作表达式)

{

    执行语句;

}

 

例如;

                                     for(int x =0;x<3;x++)

                                     {

                                               System.out.println("x="+x);

                                     }

 

for循环和while循环的区别:

1.)变量有自己的作用域,对于for来讲,如果将用于控制循环的增量定义在for语句中,那么该变量只在for语句内有效,for语句执行完毕,该变量在内存中被释放

 2.)for和while可以进行互换。如果需要定义循环增量,用for更为合适。

 

当要对某些语句执行很多次时,就使用循环结构。

 

无限循环的最简单表现形式:

for( ; ; ) { }

while ( true ) { }



break和continue单独存在时,下面不可以有任何语句,因为都执行不到,编译会失败

                                     for (int x=0;x<3 ;x++ )

                                     {

                                               continue;                     //不会执行下一句

                                               System.out.println("x="+x);          //直接跳入下个循环

                                     }

当循环嵌套时,break只跳出当前所在循环。要跳出嵌套中的外部循环,只要给循环起名字即可,这个名字称之为标号


循环利用实例:

/*
输出图形的代码:
----*
---* *
--* * *
-* * * *
* * * * *
*/
		for (int x=0;x<5 ;x++ )
		{
			for (int y=x+1;y<5 ;y++ )
			{
				System.out.print("-");
			}
			for (int z=0;z<=x ;z++ )      //由于打印没有换行,此循环的结果是接在<span style="font-family: Arial, Helvetica, sans-serif;">上一个循环的后面</span>
			{                     
				System.out.print("* ");
			}
			System.out.println();
                }





2.12 函数


函数是为了提高代码的复用性,可以将其定义成一个单独的功能,该功能的体现就是java中的函数。

 

java中函数的定义格式:

修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,……)

{

            执行语句;

            return 返回值;

}

例:


class Function 
{
	public static void main(String[] args) 
	{
		int x=getResult(4);                  //利用程序进行计算
		System.out.println("x="+x);
	}
	public static int getResult(int num)        //定义的程序
	{
		return num*3+5;
	}
}



对于函数没有具体返回值的情况,返回值类型用关键字void表示,那么该函数中的

return语句如果在最后一行可以省略不写

 

如:

                              public static void getResult(int num)

                              {

                                     System.out.println(num*3+5);              //此处没有具体返回值,返回值类型用void

                              }                                                                       

 

函数中不能定义函数,只能调用函数,返回值类型为void时,不能在打印语句中

 

如何定义一个函数?

    函数其实就是一个功能,定义函数就是实现功能,通过两个明确来完成:

    1)、明确该功能的运算完的结果,其实是在明确这个函数的返回值类型。

    2)、在实现该功能的过程中是否有未知内容参与了运算,其实就是在明确这个函数的参数列表(参数类型&参数个数)。

函数的作用:

    1)、用于定义功能。

    2)、用于封装代码提高代码的复用性。

注意:函数中只能调用函数,不能定义函数。

主函数:

    1)、保证该类的独立运行。

    2)、因为它是程序的入口。

    3)、因为它在被jvm调用。

 

如果函数名称相同,但是参数类型或个数不同,则函数重载,即使参数个数相同,相对应的参数类型如果不同,也属于重载。重载和返回值类型没关系。

 

void show ( int a,char b, double c) { }

 

void show ( int x,char y, double z) { }            //不重载

int show ( int a,double c, char b) { }               //重载

void show ( int a,double c, char b) { }            //重载

double show ( int x,char y, double z) { }        //这个函数不可以和给定函数同时存在


2.13 数组


数组时用于存储同一类型数据的一个容器。好处:可以对该容器中的数据进行编号,从0开始。数组用于封装数据,就是一个具体的实体。


元素类型[ ] 数组名 = new 元素类型 [元素个数或数组长度]  

//new是用来在内存中形成一个容器实体

int [ ]arr = new int [ 5 ]

 

元素类型[ ] 数组名 = new 元素类型 [ ] { 元素,元素,……}

int [ ]arr = new int [ ] {3,5,1,7}

int [ ]arr = {3,5,1,7}

 

int [ ] x= new int [3]; int [ ] y = x; y[1] = 89; s.o.p(x[1]); → 89

数组会在堆内存中开辟实体内存,上述x,y都指向此数组,改变y[1]的值就是在改变堆内存中数组的值,指向此数组的x的值也在同时改变。

 

ArrayIndexOutOfBoundsException:操作数组时,访问到了数组中不存在的角标。

NullPointerException:空指针异常:当引用没有任何指向值为null的情况,该引用还在用于操作实体

 

数组名称.length = 数组的长度



数组排序实例:

//选择排序
public static void sellectSort(int[] arr)              
	{
		for (int x=0;x<arr.length-1 ; x++)            //嵌套循环
		{                                        
			for (int y=x+1;y<arr.length ;y++ )    //从角标0开始依次与其之后的数进行比较,将最小值排在角标0处
			{                                     //下一次从角标1开始,将第二小值排在角标1处,以此来推进行排序
				if (arr[x]>arr[y])
				{	int bigger=arr[x];
					arr[x]=arr[y];
					arr[y]=bigger;
				}
			}
		}
	}


//冒泡排序
public static void bubbleSort(int[] arr)                       //相邻的两个元素进行比较,如果符合条件就换位
	{                                          
		for (int x=0;x<arr.length-1 ;x++ )             //第一圈:最值出现排在最后
		{
			for (int y=0;y<arr.length-x-1 ;y++ )   //-x:让每一次比较的元素减少
			{                                      //-1:避免越界
				if (arr[y]>arr[y+1])
				{
					int temp =arr[y];
					arr[y] = arr[y+1];
					arr[y+1] = temp;
				}
			}
		}
	}

无论什么排序,都需要对满足条件的元素进行位置置换。所以可以把这部分相同的代码提取出来,单独封装成一个函数。

Arrays.sort(arr)


折半查找可以提高提高效率,但是必须要保证该数组是有序的数组

public static int halfSearch(int[] arr,int key)
	{
		int min = 0,max = arr.length-1,mid;

		while(min<=max)
		{
			mid = (max+min)>>1;              //右移1位相当于除以2
			if(key>arr[mid])
				min = mid + 1;
			else if(key<arr[mid])
				max = mid -1;
			else
				return mid;
		}
		return -1;
	}




程序的应用实例:十进制转化

public static void trans(int num,int base,int offset)
	{
		if(num==0)
		{	
			System.out.println(0);
			return;
		}
			
		char[] chs = {  '0','1','2','3',           //二进制,八进制,十六进制都适用此表
				'4','5','6','7',
				'8','9','A','B',
				'C','D','E','F' };
		char[] arr = new char[32];                //char最高取到32位
		int pos = arr.length;
		while(num!=0)
		{
			int temp = num & base;            //对应二,八,十六进制,base分别为1,7,15
			arr[--pos] = chs[temp];
			num = num >>> offset;             //对应二,八,十六进制,offset分别为1,3,4
		}
		for (int x=pos;x<arr.length ;x++ )
		{
			System.out.print(arr[x]);
		}
	}
//此程序是通过给定数字,取模的基数(1,7,15),右移的位数(1,3,4),来进行进制转化