------- android培训、java培训、期待与您交流! ----------
JAVA基础知识
Java语言基础由关键字、标识符、注释、常量和变量、运算符、语句、函数和数组等组成。
1.1关键字
定义:被Java语言赋予了特殊含义的单词 特点:关键字中所有字母都为小写。
ps.
java中严格区分大小写,编辑器中蓝色字体就是关键字,红色字体就是JDK为我们提供的类。
1Byte = 8bit、1KB = 1024Byte、1MB = 1024KB、1GB = 1024MB
1.2标识符
定义:在程序中自定义的一些名称
特点:由26个英文字母大小写、0-9、_、$组成,数字不可以开头,不能使用关键字
命名规范:
包名:多单词组成时所有字母都小写。例如:xxxyyyzzz
类名、接口名:多单词组成时,所有单词的首字母大写。例如:XxxYyyZzz
变量名、函数名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写。例如:xxxYyyZzz
常量名:所有字母都大写。多单词时每个单词用下划线连接。例如:XXX_YYY_ZZZ
1.3注释
定义:用于注解说明解释程序的文字就是注释。特点:提高了代码的阅读性。
注释格式 :
单行注释://注释文字 多行注释:/*注释文字*/ 文档注释:/**注释文字*/(其中文档注释可以被解析成程序说明文档)
1.4常量
定义:不能改变的值常量分类
整数常量:所有整数。 小数常量:所有小数。 布尔(boolean)型常量:true、false。 字符常量:将一个数字字母或者符号用单引号( ' ' )标识,如:'a'。 字符串常量:将一个或者多个字符用双引号("")标识,如:"hello world"、"a"、""(空字符串)。 null常量:null。
ps.
负数的二进制表现形式就是对应的正数二进制取反加1,负数的最高位永远是1(6=0000-0110,取反加1,-6=1111-1010)
1.5变量
定义:内存中的一个存储区域,该区域有自己的名称(变量名)和类型(数据类型),该区域的数据可以在同一类型范围内不断变化。特点:变量其实就是将不确定的数据进行存储,也就是需要在内存中开辟一个空间。
格式:数据类型 变量名 = 初始化值;例如:byte b = 3
ps.
1.变量的作用范围(一对{}之间有效)。 2.变量只能存放某一类型的数据。
1.6数据类型
分类:a.基本数据类型(数值型、字符型、布尔型) b.引用数据类型(类(class)、接口(interface)、数组([]))
ps.
整数默认int类型,小数默认double类型,因此定义long类型需在数值后面加l,定义float需在后面加f。
{
public static void main(String[] args){
long l = 123456789123l;//不加l时,数值超过默认的int型范围,会报错
System.out.println(l);
}
}
{
public static void main(String[] args){
float f = 2.3f;//若不加f,则把默认的double型赋值给精度更小的float,意味着损失精度,编译会报错
System.out.println(f);
}
}
类型转换:
包括自动类型转换和强制类型转换
基本的数据类型由低级到高级(值的范围的大小)分别为:(byte、short、char)—int—long—float—doublea、自动类型转换:低级的数据类型可以自动转换为高级的数据类型
public static void main(String[] args) {
byte b=3;
int i=b;
long l=b;
float f=b;
double d=b;
System.out.println("b="+b+"i="+i+"l="+l+"f="+f+"d="+d);
}
}
输出:
b=3,i=3,l=3,f=3.0,d=3.0
b、如果低级类型为char型,向高级类型(整型)转换时,会转换为对应ASCII码值
public static void main(String[] args) {
char a='c';
int i=a+3;
System.out.println("i="+i);
}
}
输出:i=102
c、表达式的数据类型自动提升: 3.如果一个操作数是float型,计算结果就是float型; 4.如果一个操作数是double型,计算结果就是double型。
1.所有的byte型、short型和char的值将被提升到int型。2.如果一个操作数是long型,计算结果就是long型;
d、对于byte,short,char三种类型而言,他们是平级的,因此不能相互自动转换 e、强制类型转换:
public static void main(String[] args) {
byte b = 3;
b = b + 200;
System.out.println(b);
}
}
运行结果:
解决方法:进行强制类型转换,也就是将占4个字节的int类型值,再强硬存储到占1个字节的byte变量中。
public static void main(String[] args) {
byte b = 3;
b = (byte) (b + 200);
System.out.println(b);
}
}
运行结果:-53(203转换成单字节的二进制位1100-1011,首位位1系统默认为负数,结果位-53)
通过强转可以将数值强转位字符
{
public static void main(String[] args){
System.out.println((char)('a'+1));
}
}
运行结果:b
exp.....
{
public static void main(String[] args){
byte b = 3 + 7;
byte b1 = 3;
byte b2 = 7;
b = b1 + b2;
System.out.println(b);
}
}
运行结果:
原因分析:涉及到编译器编译程序时候的细节,之所以byte b = 3 +7;,没有报错,是因为3和7都是常量,编译器知道结果是10,并且在byte范围之内,因此就自动进行了强转,所以不会报错。而b = b1 + b2;中b1和b2都是变量,编译器编译程序是一行一行编译的,它根本不知道b1和b2到底是多少,两个byte类型的数据相加时,首先都会被提升为int类型,他们的和也是int类型,其值可能会超过byte的范围,因此就会报错。
{
public static void main(String[] args){
int x1 = Integer.MAX_VALUE;
x1=x1+5;
System.out.println(x1);
}
}
此程序虽然溢出但是不会报错,类型都是int。
public class Test {
public static void main(String[] args) {
char x='a';
System.out.println(x+1);
}
}
运行结果:98
p.s.
只有数值类型才能进行加法操作,因此会将字符x强转为数值
1.7运算符
1.算数运算符
ps:
负数对正数取模结果为负数。
正数对负数取模结果为正数。
{
public static void main(String[] args){
System.out.println(5%5);
System.out.println(-5%2);
System.out.println(5%-2);
}
}
运行结果:
{
public static void main(String[] args){
int a = 3,b,c;
b = a++;
System.out.println("a = " + a + ",b = " + b);
c=++a;
System.out.println("a = " + a + ",c = "+c);
}
}
运行结果:
当执行b = a++;语句时,先把a放在一个临时内存空间中,然后将a自加1,再将临时内存空间中的a赋值给b,因此b还是原来的a的值,也就是3。而执行++a时,a先自加1然后再复制给c
2.赋值运算符
符号:= , +=, -=, *=, /=, %=
exp:比较s += 4;和s = s + 4;的不同。
class OperatorDemo
{
public static void main(String[] args){
short s = 3;
s += 4;
System.out.println("s = " + s);
}
}
运行结果:
![](https://i-blog.csdnimg.cn/blog_migrate/f3e58a44ead21cb5bc000a5ea42703ca.jpeg)
说明:在执行s+=4;语句时,编译器在编译的时候,默认进行了强制类型转换,也就是将int类型的数据转换成short类型的数据。
示例3:
class OperatorDemo
{
public static void main(String[] args){
short s = 3;
s = s + 4;
System.out.println("s = " + s);
}
}
复制代码
运算结果:
说明:在执行s = s + 4;语句时,编译器在编译的时候,默认并没有强制类型转换。所以,s是short类型,4是int类型,s会自动提升为int类型,相加的和也是int类型,赋值给short类型的变量肯定会损失精度。这时候就需要进行强制类型转换:s = (short)(s + 4);
3.比较运算符
ps.
比较运算符的结果是Boolean型
比较运算符==和赋值运算符=有区别,不能搞混
4.逻辑运算符
ps.
1.逻辑运算符是连接两个Boolean型的表达式
2.&&和&运算的结果是一样的,区别在于:&&:当左边为false时,右边不参加运算,这样可以提升效率。。
3.||和|运算的结果是一样的,区别在于当左边为true时,右边不参加运算:。
因此: 使用&&和||比使用&和|更高效一些。4.java中3>a>1是不合法的
5.位运算符
ps.
1.左移几位等效于数据乘以2的几次方,右移几位相当于数据除二的几次方(效率最快)
1.与运算和相应的1位与可以提取二进制的其中几位。1001&0111→0001(取后三位)
一个数异或同一个数两次结果位本身(可以用此方法对数据进行加密,对图片数据进行异或3加密后是无法查看的,解密只需再异或3一次)
package cn.swu;
class Test
{
public static void main(String[] args){
int a =6;
int b=a^3^3;
System.out.println("a = " + a + ",b = "+b);
}
}
运行结果:a=6,b=6
class Test
{
public static void main(String[] args){
int a = 3,b = 5;
System.out.println( "a = " + a + ",b = " + b );
a = a ^ b;
b = a ^ b;
a = a ^ b;//最快实现a、b值互换
System.out.println( "a = " + a + ",b = " + b );
}
}
运算结果:a=3,b=5 a=5,b=3
6.三元运算符
(条件表达式)?表达式1:表达式2 (条件表达式为真,运算结果位表达式1,否则为表达式2)
class Test
{
public static void main(String[] args){
int a = 3,b = 10,c=12,temp,max;
temp=(a>b)?a:b;//计算a、b中的最大值
max=(temp>c)?temp:c;//计算a、b、c中的最大值
System.out.println( "temp = " + temp + ",max = " + max );
}
}
运算结果:
ps.
表达式:具有一定语法规则的语句
2 程序流程控制
1、if判断
if(boolean){执行语句}
else{执行语句}(可选操作)
多次连续判断:
if(条件表达式)
{
执行语句;
}
else if (条件表达式)
{
执行语句;
}
……
else
{
执行语句;
}
class IfDemo
{
public static void main(String[] args)
{
/*
一年有四季。
需求:根据用户输入的月份,给出对应的季节。
*/
int month = 12;
if(month<1 || month>12)
System.out.println(month+"月没有对应的季节");
else if(month>=3 && month<=5)
System.out.println(month+"月是春季");
else if(month>=6 && month<=8)
System.out.println(month+"月是夏季");
else if(month>=9 && month<=11)
System.out.println(month+"月是秋季");
else
System.out.println(month+"月是冬季");
}
}
运行结果:12月是冬季
2、switch选择
switch(表达式)
{
case 取值1:
执行语句;
break;
case 取值2:
执行语句;
break;
…...
default:
执行语句;
break;
}
switch语句特点:
1、switch语句选择的类型只有四种:byte,short,int,char。
2、没有匹配的case执行default。
3、结束switch语句的两种情况:①遇到break,②执行到switch语句结束。
4、如果匹配的case或者default没有对应的break,那么程序会继续向下执行,运行可以执行的语句,直到遇到break或者switch结尾结束。
5、进入switch语句后,执行顺序是先执行case,然后从上到下,最后再执行default。即使default放在case上面,执行顺序也不变。
/*
* 需求:判断对应月份所属的季节
* */
public class Test {
public static void main(String[] args) {
int num=12;
switch(num)
{
case 3:
case 4:
case 5:
System.out.println(num+"月是春季");
break;
case 6:
case 7:
case 8:
System.out.println(num+"月是夏季");
break;
case 9:
case 10:
case 11:
System.out.println(num+"月是秋季");
break;
case 12:
case 1:
case 2:
System.out.println(num+"月是冬季");
break;
default:
System.out.println(num+"没有对应的季节");
break;
}
}
}
运行结果:12月是冬季
P.S.
if:
1. 对具体的值进行判断。
2. 对区间判断。
3. 对运算结果是boolean类型的表达式进行判断。
switch:
1. 对具体的值进行判断。
2. 值的个数通常是固定的。
对于几个固定的值判断,建议使用switch语句,因为switch语句会将具体的答案都加载进内存,效率相对高。
3、while循环
a、while(条件表达式){循环语句;}
b、do{
执行语句;
}while(条件表达式)
while和do while的区别
public class Test {
public static void main(String[] args) {
int num=1;
while(num>1){
System.out.println("while");//条件不满足时while一次都不执行
}
do{
System.out.println("do while");//无论条件是否满足时do while至少执行一次
}
while(num>1);
}
}
运行结果:
4、for循环
for(初始化表达式;条件表达式;循环后执行表达式){
执行语句;
}
执行顺序:
初始化表达式只读一次,判断循环条件,为真就执行循环体,然后再执行循环后的操作表达式,接着继续判断循环条件,重复找个过程,直到条件不满足为止。
while和for的区别
while和for可以变换使用,但是区别在于for为了循环而定义的变量在for循环结束就在内存中释放,而while循环使用的变量在循环结束后还可以继续使用。
public class Test {
public static void main(String[] args) {
int x=0;
while(x<4){//循环结束后,变量x还存在
System.out.println("x="+(x++));//条件不满足时while一次都不执行
}
for(int y=0;y<4;y++)//循环结束后,变量y就会释放
{
System.out.println("y="+y);
}
System.out.println("x="+x);
}
}
运行结果:
a、for循环的嵌套
/*
需求:打印5行的三角和倒三角
* */
public class Test {
public static void main(String[] args) {
for(int x=0;x<5;x++){//打印倒三角
for(int y=0;y<5-x;y++){//一行有几列
System.out.print("*");//换行
}
System.out.println();
}
for(int x=0;x<5;x++){//打印三角
for(int y=0;y<=x;y++){//一行有几列
System.out.print("*");
}
System.out.println();//打印完一行换行
}
}
}
运行结果:
/*
需求:打印9*9乘法表
* */
public class Test {
public static void main(String[] args) {
for(int x=1;x<10;x++){
for(int y=1;y<=x;y++){
System.out.print(y+"*"+x+"="+x*y+"\t");// /t为制表符
}
System.out.println();//打印完一行换行
}
}
}
P.S.
\t是制表符,windows中回车符由来两个符号组成\r\n
/*
需求:打印
* * * * *
* * * *
* * *
* *
*
* */
public class Test {
public static void main(String[] args) {
for(int x=1;x<=5;x++){
for(int y=1;y<x;y++){
System.out.print(" ");//先打印每一行的空格
}
for(int z=5;z>=x;z--){
System.out.print("* ");//再打印“* ”
}
System.out.println();//打印完一行换行
}
}
}
3 数组
数组:装载同一类型数据的一个集合(容器)
格式:
元素类型[] 数组名=new 元素类型[数组长度];
元素类型[] 数组名=new 元素类型[]{元素1,...元素3};
数组在内存中的分配特点:
P.S
Java程序在运行时,需要在内存中分配空间。为了提高运算效率,又对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
1. 寄存器。
2. 本地方法区。
3. 方法区。
4. 栈内存:用于存储局部变量,当变量所属的作用域一旦结束,所占空间会自动释放。
5. 堆内存:数组和对象,通过new建立的实例都存放在堆内存中各数据类型默认的初始化值,整数类型是0,小数类型是0.0或0.0f,boolean类型是false,char类型是'\u0000'。
a、排序
/*
需求:将数组中的内容按从大到小排序
思路:
选择排序:从第一个元素开始,分别与后面的元素比较,并将较大者存储在前面
冒泡排序:从第一个元素开始,相邻两个元素进行排序,大的往左边走,晓得往右边走
*/
public class Test {
public static void main(String[] args) {
int[] arr1={12,14,3,26,1,-3};
System.out.print("排序前数组:");
printArray(arr1);
System.out.print("选择排序:");
selectArr(arr1);
printArray(arr1);
int[] arr2={12,14,3,26,1,-3};
System.out.print("排序前数组:");
printArray(arr2);
System.out.print("冒泡排序:");
bubbleArr(arr2);
printArray(arr2);
}
public static void selectArr(int[] arr){//选择排序
int max=0;
for(int x=0;x<arr.length;x++){//依次与后面所有的元素比较
for(int y=x+1;y<arr.length;y++){
if(arr[y]>arr[x]){//
max=arr[y];
arr[y]=arr[x];
arr[x]=max;
}
continue;
}
}
}
public static void printArray(int[] arr){
System.out.print("[");
for(int x=0;x<arr.length;x++){
System.out.print(arr[x]);
if(x!=(arr.length-1))
System.out.print(",");
else
System.out.println("]");
}
}
public static void bubbleArr(int[] arr){//冒泡排序
for(int x=0;x<arr.length;x++){
for(int y=0;y<arr.length-x-1;y++){//相邻两个元素比较
if(arr[y+1]>arr[y]){
arr[y]=arr[y]+arr[y+1];
arr[y+1]=arr[y]-arr[y+1];
arr[y]=arr[y]-arr[y+1];
}
continue;
}}
}
}
b、查找
数组是无序的可以用循环遍历去查找,但是当数组是有序的可以用二分法,每次与中间值比较,不断的缩小范围,最后得出结果
/*
需求:用二分查找法,找出对应元素在数组中的位置
思路:
1、定义三个角标变量min、mid、max,其中mid=(min+max)/2
2、元素先和mid对应的元素比较,相同则输出,不同则比较大小,将中间量相应的替换最大最小量重新使用二分法
*/
public class Test {
public static void main(String[] args) {
int num=6;
int[] arr={-1,0,6,7,8,9,13,15};
int index=find(num,arr);//定义一个方法查找对应的角标
System.out.println("num="+num+"对应的角标为:"+index);
}
public static int find(int num,int[] arr){
int min=0;//最小角标
int max=arr.length-1;//最大角标
int mid=0;
while(num!=arr[mid]){//每次判断中间元素与元素是否相等
if(num>arr[mid])
min=mid+1;//如果元素大于中间量,取后半段数组继续类推比较
else if(num<arr[mid])
max=mid-1;
mid=(min+max)/2;//mid为中间量角标
}
return mid;
}
}