变量就是系统为程序分配的一块内存单元,用来存储各种类型的数据。由于该存储单元中的数据可以发生改变,因此得名为"变量"。(通俗的讲,变量就是内存块的标识符)
变量分类:
按所属的数据类型划分:
基本数据类型变量
引用数据类型变量
按被声明的位置划分:
局部变量:方法或语句块内部定义的变量 。局部变量没有默认初始值;
成员变量:方法外部、类的内部定义的变量。成员变量有默认初始值;
特别注意:类的外面不能有变量的声明
由于变量记录的数据内容大小以及类型不同, 导致所需的存储单元大小不同,在 Java 语言中使用数据类型的概念加以描述。
字节是计算机信息技术用于计量存储容量的一种计量单位,作为一个单位来处理的一个二进制数字串,是构成信息的一个小单位。Java 中的字节是8比特位的字节,即它包含八位的二进制数。
8种基本数据类型:
类型 | 占用内存 | 值范围(含边界值) | 默认值 |
---|---|---|---|
整数型(int) | 4 字节 | -2 147 483 648 ~ 2 147 483 647(稍大于 20 亿) | 0 |
短整数(short) | 2 字节 | -32 768 ~ 32 767 | 0 |
长整数(long) | 8 字节 | -9 223 372 036 854 775 808L ~ 9 223 372 036 854 775 807L | 0 |
字节型(byte) | 1字节 | -128 ~ 127 | 0 |
浮点型(float) | 4 字节 | -3.40292347E+38-3.40292347E+38 | 0.0f |
双 精 度 型(double) | 8 字节 | -1.79769313486231570E+308-1.79769313486231570E+308 | 0.0d |
布尔型(boolean) | 1 字节 | true 或 false | false |
字符型(char) | 2 字节 | ‘ \u0000 - u\ffff ’ | ‘\u0000’ |
引用数据类型:
类、接口、数组;
- 引用数据类型本质上就是通过指针,指向堆中对象所持有的内存空间,只是Java语言不再沿用指针这个说法而已。
- 若JAVA中数组元素没有初始化,会给定一个默认的初始值。
byte,short,int,long类型定义的数组,默认值是0;
float、double类型定义的数组,默认值是0.0;
boolean类型定义的数组,默认值是false;
char类型定义的数组,默认值是 ’ ’ (’\u0000’);
String类型定义的数组,默认值是null。
Java 对包、类、方法、参数和变量等要素命名时使用的字符序列称为标识符。规则如下:
标识符命名习惯:见名知意。
命名规范: 软性建议
类名规范:首字母大写,后面每个单词首字母大写(大驼峰式)。
方法名、参数名、成员变量、局部变量都统一使用规范: 首字母小写,后面每个单词首字母大写(小驼峰式)。
常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。 正例:MAX_STOCK_COUNT 或者 CACHE_EXPIRED_TIME
boolean 类型不能转换成任何其它数据类型。
**自动类型转换:**容量小的类型自动转换成容量大的数据类型 byte,short,int -> float ->long ->double
byte,short,int 不会互相转换,它们三者在计算时会转换成 int 类型
**强制类型转换:**容量大的类型转换成容量小的数据类型时,要加上强制转换符
long l = 100L;
int i = (int)l;
但是有可能造成精度降低或数据溢出,使用时要小心。
默认变量右边的整数(常数)为int,如果要表示长整型,需要在数值后面加L
如long ll = 2147483648L;
默认变量右边的小数为double类型,如
float f = 1.2;
是不被允许的
float f1 = 1.2f; // 向计算机表示这是浮点类型
float f2 = 1; // 发生自动类型转换a +=1和a=a +1的区别?
a += b 等价于 a=(a.Type)(a+b); //返回的是a类型,强制转换
a = a+b 等价于 a=a+b; //返回类型是a类型与b类型中的最高类型
Java 中有一些赋予特定的含义,有专门用途的字符串称为关键字(keyword)。全部是小写。(高亮的关键字表示很少用到)
abstract | boolean | break | byte | case | catch |
---|---|---|---|---|---|
char | class | const | continue | default | do |
double | else | extends | final | finally | float |
for | goto | if | implements | import | instanceof |
int | interface | long | native | new | package |
private | protected | public | return | short | static |
strictfp | super | switch | synchronized | this | throw |
throws | transient | try | void | volatile | while |
assert | enum |
保留字:没有定义用途,但保留备用。 如goto、const.
概述:
方法用于封装一段特定的逻辑功能。方法的主要要素有:权限修饰符 方法名、参数列表和返回值。
格式:
权限修饰符 返回值类型声明 方法名称(参数列表) {
方法中封装的逻辑功能;
return 返回值;
}
权限修饰符详解
在修饰成员变量/成员方法时,该成员的四种访问权限的含义如下:
注意 使用场景在同一个包下面,protected和default表现一致。不在同一个包下面,对于default,在任何场景均不能使用对象直接调用被修饰的属性和方法,而对于protected,只有子类可以访问父类的被修饰的属性或方法。
在修饰类时,该类只有两种访问权限,对应的访问权限的含义如下:
返回值详解
方法调用结束后可以返回一个数据,称之为返回值。
方法在声明时必须指定返回值的类型。
通过 return 语句返回,return 语句的作用在于结束方法且将数据返回。
如果方法没有返回值(即方法不需要返回数据),需将返回值类型声明为 void。
参数列表详解
方法的参数列表:在调用时传递给方法,需要被方法处理的数据。
在方法定义时,需要声明该方法所需要的参数变量。
在方法调用时,会将实际参数值传递给方法的参数变量。必须保证传递参数的类型和个数符合方法的声明。
算术运算符
++: 如果是变量前缀:先对此变量加 1,再执行其他的操作。
如果是变量后缀:先执行当前语句的其他操作,再对此变量加 1
–: 如果是变量前缀:先对此变量减 1,再执行其他的操作。
如果是变量后缀:先执行当前语句的其他操作,再对此变量减 1
逻辑运算符
逻辑运算符用于对 boolean 型结果的表达式进行运算,运算结果总是 boolean 型
运算符 | 描述 |
---|---|
& | 与 |
^ | 异或 |
| | 或 |
! | 非 |
&& | 短路与 |
|| | 短路或 |
&&只要一个条件为假则返回false,不会去判断所有条件
||只要一个条件为真则返回true,不会去判断所有条件
相比于&和|,使用&&和||能提高运行效率
**注意 **使用++ 和–的小技巧:a++ 和++a 都是将a 加1,但是a++ 返回值为a,而++a 返回值为a+1。如果只是希望增加a 的值,而不需要返回值,则推荐使用++a,其运行速度会略快一些。
所有的ASCII码都可以用“\”加数字(一般是8进制数字)来表示。而C中定义了一些字母前加"\"来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,就称为转义字符,因为后面的字符,都不是它本来的ASCII字符意思了
转义字符 | 意义 | ASCII码值(十进制) |
---|---|---|
\n | 换行,将当前位置移到下一行开头 | 010 |
\r | 回车 ,将当前位置移到本行开头 | 013 |
\t | 水平制表(HT) (跳到下一个TAB位置) | 009 |
\ | 代表一个反斜线字符’’’ | 092 |
’ | 代表一个单引号(撇号)字符 | 039 |
" | 代表一个双引号字符 | 034 |
在window中需要\n\r 才能实现换行
调用Scanner类
import java.util.Scanner; Scanner input = new Scanner(System.in)
方法一,输入指定类型变量的值
方法二,输入的类型统一为字符串
string str1 = input.next(); string str1 = input.nextLine();
next和nextLine的区别?
next 遇到空格或回车会结束,如果一开始就输入空格,会继续读取到有效字符为止,遇
到空格或回车才会结束
nextLine()方法字面上有扫描一整行的意思,它的结束符只能是Enter键,即nextLine()方
法返回的是Enter键之前没有被读取的所有字符,它是可以得到带空格的字符串的。
注意事项:
""
。所以若在input.nextInt()和input.nextDouble()后使用input.nextLine(),要先加一个input.nextLine()进行换行。如何判断用户输入的类型?为维护代码的健壮性,当用户输入错误时程序不至于崩掉
import java.util.Scanner; public class Demo { /** * 接受用户输入,如果用户输入类型有误则给出提示 * @param args */ public static void main(String[] args) { Scanner input = new Scanner(System.in); if (input.hasNextInt()) { int i = input.nextInt(); System.out.println("您输入的数字是:" + i); } else { System.out.println("您的输入有误,请检查!"); } input.close(); } }
一、if 条件语句
if 条件结构是根据条件判断之后再做处理
if(条件语句){…}
if (条件语句){…}else{…}
if (条件语句){…}else if(条件语句){…}
if (条件语句){…}else if(条件语句){…}else{…}
二、switch 语句
switch(表达式){
case 取值 1: 语句块 1;break;
case 取值 n: 语句块 n;break;
default: 语句块 n+1;break;
}
switch 语句有关规则 表达式的返回值必须是下述几种类型之一:int, byte, char, short,String;
case 子句中的取值必须是常量,且所有 case 子句中的取值应是不同的;
default 子句是可选的;
break 语句用来在执行完一个 case 分支后使程序跳出 switch 语句块;如果 case 后面没有写 break 则直接(不管case条件满不满足)往下面执行,直到遇到break语句! Case 后面的执行体可写{ }也可以不写{ }
if和switch的区别:if可以进行区间,非等值的比较,而switch适合等值比较,if用的比较多。
一、简介
循环语句功能 在循环条件满足的情况下,反复执行特定代码
循环语句分类
二、while 循环
符合条件,循环继续执行;否则,循环退出 特点:先判断,再执行
语法:
while(条件表达式){
//语句块;
}
使用 while 循环的步骤
1、分析循环条件和循环操作
2、套用 while 语法写出代码
3、检查循环是否能够退出
三、do-while 循环
先执行一遍循环操作,符合条件,循环继续执行;否则,循环退出
特点:先执行,再判断
语法:
do {
循环操作
}while ( 条件表达式 );
while 循环和 do-while 循环的区别?
while:先判断条件,如果条件满足,再执行循环操作 do while:先执行一遍循环操作,然后再判读条件,如果条件满足,继续执行循环操作。
四、for 循环
语法:
for(初始化参数;判断条件 ;更新循环变量){
循环体;
}
break 和continue的区别?
break 是用于终止本轮所有次循环,即不执行本次循环中break后面的语句,直接跳出循环
continue 是用于终止本次循环,即本次循环中continue后面的代码不执行,进行下一次循环的入口判断
如何跳出多层循环?
答:给循环起个标识符,使用break 标识符;
即可跳出多重循环
break只能跳出单层循环
例如
public class Demo { /** * 跳出多层循环 * * @param args */ public static void main(String[] args) { heihei: for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { System.out.println("i=" + i + " j=" + j); if (i == 5 & j == 5) { break heihei; } } } } }
数组是相同数据类型的多个数据的容器 。数组的长度在创建时就固定了!
创建一维数组的方式
数据类型 [] 数组名称 = new 数据类型 [数组长度];
数据类型 [] 数组名称 = { 数组内容 1, 数组内容 2, 数组内容 3… 数组内容 n};
数据类型 [] 数组名;
只创建了数组引用名, 并未在内存创建数组空间。
数据类型 [] 数组名称 = new 数据类型[]{ 内容 1, 内容 2, 内容 3… 内容 n};
// 常用方式一:创建数组的同时,指定数组中的内容 int[] ages1 = {10, 11, 12, 13}; // 常用方式二:创建数组,指定数组的长度,不指定数组中的内容(默认内容,如int数组默认为0) int[] ages2 = new int[10]; // 获取数组ages1的长度 int len = ages1.length // 不常用方式1:不初始化,且初始化的方式唯一 int [] num; // 只是申请了一个空指针,没有指向内存空间,而且这个指针变量没有默认值 num = new int[10]; // 不能使用num = {10, 11, 12, 13}; // 不常用方式2:指定数组中的内容 int[] ages = new int[]{10, 11, 12, 13};
动态扩容详解:无需真正增加原数组的容量,只用将原内容复制到新的大数组,然后让原数组名称重新等于大数组即可。由于原数组数据在堆中, 失去引用会被 GC 自动回收。
使用数组容易出现的问题:
超出长度的下标操作,数组越界异常
数组未赋值:空指针异常
int [] num = null; System.out.println(num[1]);
创建二维数组
int[][] nums = new int[10][];// 行数必填,列数选填,如果填了列数则每行的列数一样 nums[0] = new int[]{1, 2, 3};
修饰符 | 类 | 包 | 子类 | 其他包 |
---|---|---|---|---|
public | ∨ | ∨ | ∨ | ∨ |
protect | ∨ | ∨ | ∨ | |
default | ∨ | ∨ | ||
private | ∨ |
详细请见上面第六点
定义整型变量 a 、 b ,写出将 a 、 b 两个变量值进行互换的程序(要求不能使用第三个变量)
方法一
int a = 2, b = 1; a = a + b; b = a - b; a = a - b;
方法二
int a = 2, b = 1; a = a^b; b = a^b; a = a^b;
冒泡排序
public class Demo { /** * 冒泡排序 */ public static void main(String[] args) { int[] nums = { 12, 43, 2, 7, 0, -1 }; System.out.println("排序前:"); for (int i = 0; i < nums.length; ++i) { System.out.print(nums[i] + "\t"); } int temp; // 外层循环控制冒泡次数 for (int i = 0; i < nums.length - 1; ++i) { // 内层循环控制比较次数 for (int j = 0; j < nums.length - i - 1; ++j) { if (nums[j] > nums[j + 1]) { temp = nums[j]; nums[j] = nums[j + 1]; nums[j + 1] = temp; } } } System.out.println(); System.out.println("排序后:"); for (int i = 0; i < nums.length; ++i) { System.out.print(nums[i] + "\t"); } } }
二分查找
public class Demo { public static void main(String[] args) { int[] nums = { -1, 0, 2, 7, 12, 43 }; int target = 12; int minIndex = 0; int maxIndex = nums.length - 1; int midIndex = (minIndex + maxIndex) / 2; while (true) { System.out.println("循环了一次"); if (nums[midIndex] == target) { break; } else if (nums[midIndex] > target) { maxIndex = midIndex - 1; } else minIndex = midIndex + 1; if (minIndex > maxIndex) { midIndex = -1; break; } midIndex = (minIndex + maxIndex) / 2; } System.out.println("下标为" + midIndex); } }