关键字:(51个关键字必须记住)
概述:被Java语言赋予特殊含义的单词。
特点:组成关键字的字母全部是小写。
标识符:
概念:就是给类、接口、方法、变量等起名字。
组成规则:
1、英文字母大小写
2、数字字符
3、$ _组成
注意事项:
不能以数字开头
不能是Java中的关键字
Java命名规则(见名知意):
包(其实就是文件夹。把相同的类名区分开):必须每个单词都要小写。
类或者接口:单个单词:首字母大写,如:Test 多个单词:每个首字母都要大写 StudentTest
方法或变量:单个单词:首字母要小写。 多个单词:首字母小写,其余单词首字母大写,如:studentAge()
常量:单词中的每一个字母都要大写。 多个单词:单词之间用_组成。
注释:
注释标准:给自己和别人看的,一段代码中最少有三分之一是注释。
分类:单行注释//
多行注释/* /
文档注释/* */
作用:用于解释说明程序
可以排除程序的BUG;
常量和变量:
常量:在程序执行的过程中,其值不可发生改变
字面值常量: 1、字符串常量(constant)如:”char“
2、整数常量:100
3、字符常量:‘a’
4、小数常量:10.23
5、布尔常量:true false
6、空常量:null
进制:X进制就是人们定义的进位方法,规则是逢X进一。
有二进制:以0b开头
八进制:由0开头
十进制:整数的默认为十进制
十六进制:由0x开头。
进制之间的转换:
-
X进制转换为十进制:
系数:每一个位上的数据值本身就是系数 基数:X进制的基数就是X 权:我们针对每一个位上的数据进行编号,从右边,并且是从0开始编号,这个编号就是该为上数据的权值 每一个位上的系数+基数^权次幂相加; 如:ob 01101101 -----> 1*(2^6)+1*(2^5)+1*(2^3)+1*2^2+1*2^0(十进制)
-
十进制转换为X进制:
将十进制作为被除数,以x作为除数,得到余数,依次向下面除数,一直到,商为零的时候,将余数从下到上排列。
原码,反码,补码
源码:最高位中0为正数,1为负数
反码:正数的反码与原先的相同,负数的反码是符号位不变,数值位取反。
补码:正数的补码与原码相同。
负数的补码是在反码的基础上加1。
负数的原码的求法:-x,先求x的补码,将x的补码自动补齐到32位或者64位,将最高位改为1,就得到这个负数的原码
正数与正数相加,负数与负数相加,正数与负数相加,无论是哪一种加法,都要在补码层面进行,进位的删去,
byte1个字节,范围:–128 ~ 127 ,不符合原反补的一些规则,比如:10000000 -->就是-128 ,11111111 —>就是-1.
1.变量
数据类型:基本数据类型和引用数据类型
基本数据类型:整数,浮点数,字符型,布尔型(4型)
8类:整数:byte(1个字节) short(两个字节) int(4个字节) long(8个字节)
浮点数:float(4个字节) double(8个字节)
字符型:char(2个字节)
布尔型:Boolean(1个字节)
注意:整数类型:以int为默认值,浮点数以double为默认类型。
变量的使用规则:
作用域:变量定义在那一级大括号中,那个大括号的范围就是这个变量的作用域。相同的作用域中不能定义两个相同的同名变量。
初始化值:没有初始化值的变量不能直接使用。
类型的转换:
默认转换:从小的转换大的类型,比如:程序如下
class Test{
public static void main(String[] args){
int a=4;
byte b=5;
int c=a+b;/*(正确,这里byte变量参与与int类型加法时,先转换为int类型,在相加,得到一个int类型的数据放在int类型的数据c中。)*/
byte d=a+b/*错误,经过转换后a+b的类型为int类型,在内存中是4个字节,byte类型的d在内存中是一个字节。所以,将a+b放入d的内存时,会由3个字节的损失。*/
}
}
强制转换:
概念:由大转小。
方法:(要转换的类型名)(被转换的数据)
ASCII码值(记住3个):‘a’: 97
‘A’ 65
‘0’ 48
运算符:
分类:算术运算符:
+ - * / % ++ - -
/是取整数
%是取余数
**++ - -
用法:
单独使用:无论放在操作数前面还是后面,都是自增和自减
参与运算:
放在操作数前面,是先进行自增或自减,在参与运算。++a;
放在操作数后面,先参与运算,在进行自增或自减。a++;
如:
class Test{
public static void main(String [] args){
int a = 1;
int b = 2;
int c;
int d;
c=++a;
d=--b;
System.out.println("c="+c);//运行结果是2
System.out.println("d="+d);//运行结果是1
}
}
//**放在操作数的后面,先参与运算,在进行自增或自减**
class Test{
public static void main(String [] args){
int a = 1;
int b = 2;
int c;
int d;
c=a++;
d=b--;
System.out.println("c="+c);//运行结果1
System.out.println("d="+d);//运行结果是2
}
}
赋值运算符:
= != 等等
扩展的赋值运算符:
+=,-=,/=,
注意:y=y+1;与语句y += 1;是一样的吗?
解答:得到的结果y的值是一样的。但y += 1里面隐藏了强制的类型转换。如:
class Test02{
public static void main(String[] args){
short y=1;
y=y+1/*jvm运行时会报错,因为y参与运算时先将short类型转换为int类型。在与1相加,得到的结果赋给short类型的y,这会损失精度。*/
y+=1//正确,这一句相当于:y=(short)(y+1);
}
}
比较运算符:
!= ==
注意:== 与= 的区别,==是比较运算符,得到的结果是boolean类型,=是赋值运算符。将值赋给变量或者const(常量)
逻辑运算符:
& , | ,^ ,!
&& ,||
特点:逻辑运算符一般用于连接boolean类型。
结论:
&逻辑与:有false则false;
|逻辑或:有true为true;
^逻辑异或:相同为false,相异为true;
&& 与& 的区别:
&&具有短路效果,当左边为false时,就不执行右边(因为右边不论时true还是false结果都是false)。&就必须把判断跑完才得到结论。
||与|的区别:
||具有短路效果,当左边为true时,就返回结果。
位运算符:
/* 位运算在内存中都是用二进制在进行。(& | ^ ~)
* 10在内存中的二进制 00000000 00000000 00000000 00001010
* 20在内存中的二进制 00000000 00000000 00000000 00010100
* 00000000 00000000 00000000 00001010
* & 00000000 00000000 00000000 00010100 & (遇false则false)
* -----------------------------------------------------------------------
* 00000000 00000000 00000000 00000000 结果是0;
*
* 00000000 00000000 00000000 00001010
* | 00000000 00000000 00000000 00010100 | (遇true则true)
* -------------------------------------------------------------------------
* 00000000 00000000 00000000 00011110 结果是2+4+8+16=30
*
* 00000000 00000000 00000000 00001010
* ^ 00000000 00000000 00000000 00010100 ^ (相同为0,相异为1)
* -----------------------------------------------------------------------
* 00000000 00000000 00000000 00011110 结果是30
*
*
* ~ 00000000 00000000 00000000 00010100 ~(全部取反。)
* -------------------------------------------------------------------------
* 11111111 11111111 11111111 11101011(补码,前面的运算结果为正数,正数的原反补相同)
* 反码:11111111 11111111 11111111 11101010
* 原码:10000000 00000000 00000000 00010101 结果为-(1+4+16)= -21
*
* */
<<(左移) >>(右移) >>>(无符号左移)
规则:<<:向左边移动,右边空缺则补0;
>>:向右边移动。左边最高位为1则补1,最高位为0则补0
>>>:无符号右移。最高位无论是0还是1,都补齐为0
结论:3 << 2 :3左移2位,将移动的数乘以 2的位数次幂,即:3X2^2
3 << 3 :3左移3位,将移动的数乘以 2的位数次幂,即:3X2^3,一般左移都会使数字增大。
面试题:
如何一最效率的方式计算出3与8的乘数
3*8,是错误的。答案是:3 <<3
三目运算符:
格式:(比较表达式)? x : y;
规则:当比较表达式的结果为真时,则返回x,否则返回y;
语句:
键盘录入:
三步:1.导包,import java.util.Scanner;
2.创建Scanner类的对象,
如:Scanner sc = new Scanner(System.in);
3.引用对象的nextInt()方法
int t = sc.nextInt();//输入的int类型的值
String s = sc.nextLine();
选择分支结构:
***if ……else语句。三种表现形式***:
1、if(比较表达式){
}
2、if(比较表达式){
语句体
}else{
}
这种形式与三目运算符用法相同,能达到相同的目的,但是,这种一个if ……ekse 结构中,语句体可以用输出语句,但三目运算,中返回的是一个类型。
3\if(比较表达式){
}else if (){
}
……
else {
}
switch语句:
格式:switch(表达式)
{
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
...
default:
语句体n+1;
break;
}
switch括号中的表达式的取值的限制:byte,short,int ,char
在jdk1.5版本之后,可以是枚举
在jdk1.7版本后,字符串也可以。
***循环语句***
三种格式:
1、for(初始化; 判断表达式;控制表达式){
循环体;
}
2、while语句
初始化;
while(判断表达式){
循环体;
控制表达式;
}
3、do…while语句
变量初始化
do
{
循环体;
控制表达式;
}while(判断表达式)
for、while、do…while语句的区别用法:
for与while都是先进行判断,在执行循环体。do…while是先执行一次循环体,在进行判断。
for可以在条件明确时使用。while可以在条件未明确时使用 ;
如:题(我国最高的山峰时珠穆朗玛峰,高度是8848m,现在有一张纸,厚度1米,问:将这张纸张折叠多少次,才能比珠峰告)
代码为:
class Test{
public static void main(String[] args){
int end = 8848;//山峰的高度
int strat = 1;
while(strat < end) {
strat *= 2;
}
System.out.println(strat);
}
}
在日常中一般都用for(;;)循环语句;
两种死循环:while(true){ },for(; ; ){ }
break,continue,return 的区别:
break是退出这个循环,是这个循环不在执行;
continue 是结束本次循环,在继续进行下一次的循环。
return 不是结束循环的,而是结束方法的。
一但遇到return程序就不在执行。
函数:(方法)
通俗讲方法就是完成特定功能的代码块。通过给这段代码起名,然后要用到这个功能时 ,就通过这个方法名调用这个方法实现这个功能,解决了代码的臃肿问题。
方法的格式:
修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2…){
方法体语句;
return 返回值;
}
详细解释:
修饰符:目前就用 public static。后面我在学习到其他的修饰符。
static对方法进行声明,就可以直接用类名称调用此方法
返回值类型:就是功能结果的数据类型。
方法名:符合命名规则即可,方便调用。
参数:
实际参数:就是实际参与运算的。
形式参数:就是方法定义上的,用于接受实际参数的。
参数类型:就是参数的数据类型。
参数名:就是变量名。
方法体语句:就是完成功能的代码块。
return:结束方法的。
返回值:就是功能的结果。由return带给调用者。
举例:
class FunctionDome{
public static void main(String[] args){
int x = 10;
int y = 30;
int result = sum(x,y);
System.out.println(result);
}
public static int sum(int a,int b){
return a+b;
}
}
方法的特点:
1、不调用,不执行。(2次重看)
2、方法是同级的,不能在方法中定义方法。
方法怎么调用?
1、(有明确的返回值类型)
A:单独调用。没有意义,比如:sum(x,y);
B:输出调用,没有太大的意义,比如:System.out.println(sum(x,y));
C:赋值调用,推荐使用,比如:int result = sum(x,y);
图解:
2、(没有明确返回值的调用void(空))
例如:
class Test2{
//需求:在控制台上输出m行n列的*****符号。
public static void main(String[] args){
priintlnxing(4,5);//单独调用,可以输出结果
//System.out.println(pringxing(4,5));输出调用。编译报错,没有办法输出空类型。
//void v = pringxing(4,5);赋值调用。编译出错。
}
/*分析:两个明确:
返回值类型:这个时候没有明确的返回值,但不写东西不行,所以记住这里是void(空)
参数列表:int m, int n;*/
public static void printlnxing(int m, int n){
for(int i = 0;i<m;i++){
for(int j = 0;j<n ;j++){
System.out.print("*")
}
System.out.println();
}
}
}
所以总结:当没用明确的返回值类型的时候,返回值类型就用void(空),且调用只能进行单独调用。
方法的参数,无限传参
package com.test;
public class tostring_test extends Object {
public static void main(String[] args) {
// TODO Auto-generated method stub
//无限传参
int s = tostring_test.Test(1,2,3,4,56,89,75,4,5,2,5);
System.out.println(s);//11
}
public static int Test(int... num2) {
return num2.length;
}
}
方法的重载
定义:在一个类中,方法名相同,但方法的参数类型或参数个数不同叫方法重载。
注意:方法重载与参数类型没有关系。
jvm在调用方法时,会根据参数列表不同来区分同名的方法。
数组:
数组是可以存储多个变量的容器。
数组中多个变量的数据类型必须一致。即:
数组是存储同一个数据类型的多个元素的集合。
数组可以存储基本数据类型,也可以存储引用数据类型。
数组的格式:
数据类型[] 数组名;叫法为:定义了一个数据类型数组的变量**;常用第一种。**
数据类型 数组名[]; 叫法为:定义了一个类型为数据类型的数组变量。
数组的初始化:
动态初始化:给数组给定大小,由系统给与初始化值。 int[] a = new int[3];
java内存空间分配问题:
java为了提高程序的效率,就对数据进行了不同空间的分配。具体的是划分为了如下5个内存空间。
栈:存放的是局部变量。局部变量->在方法定义中或方法声明上的变量都称为局部变量。
堆:存放的是所有new出来的东西。
方法区:(面向对象)
本地方法区:(系统相关)
寄存器:(cpu使用)
重点讲解的是堆和栈的内容:
1、堆:存放所有new出来的东西;如:int[] a = new int[3];
分析:在这段代码中前面是在方法中定义所以是局部变量,故int[] a存放在栈中,而new int[3]存放在堆中。
堆的特点:1、每一个new出来的值都有地址值(一般用16进制数表示)
2、每个变量都有默认值
byte ,short,int ,long 0;
float ,double 0.0;
char '\u0000';
boolean false;
引用类型 null;
3、使用完毕后就变成垃圾,但是没有被立即回收,等到垃圾回收器空闲时再回收。
栈的特点:1、存放局部变量。
2、栈内存的数据用完就释放掉
分析:int[] a = new int[3];
当new int[3]时,堆就为 new 的int[3]分配了空间资源,在数组的第一个位置有一个地址,在将这个地址赋给int[] a,而数组在栈中通过这个地址指向堆分配的内存空间。故调用时:数组名[索引];(索引就是数组元素的编号,从0开始,一直到数组长度-1)。
System.out.println(a);输出的是一个地址值。
静态初始化:给数组每一个元素初始化值,由系统给数组分配大小。 如:int[] arr = new int[]{1,2,3}
即:格式为:数组类型[] 数组名 = new 数组类型[]{元素值1,元素值2,…}
可以简化为:数组类型[] 数组名 = {元素值1,元素值2…} 如:int[] arr1 = {1,2,3}
注意:数组不能同时动态和静态初始化。如:int[] arr = new int[3]{1,2,3};//错误的写法。
两个使用数组常见错误:(越界和空指针)
class Test2{
public static void main(String[] args){
int[] arr = {1,2,3};
System.out.println(arr[3])//数组越界,arr数组只有0,1,2
arr = null;
System.out.println(arr[1]);//空指针,没有指向堆内存的空间,无法访问里面的内容。
//ArrayIndexOutOfBoundsException(数组索引越界异常)<问题>
//<原因>(你访问了不存在的数组)
//<解决>(修改出问题的数组处,改为能访问的数组索引)
//NullPointerException(空指针)
//<原因>(将null赋值给了数组名)
//<解决>(删掉)
}
}
数组的遍历:
int[] arr = {1,2,23,43};
for(int i = 0;i<arr.lenght;i++){
System.out.println(arr[i]);
}
输出结果:1
2
23
43
这里有一点注意:数组名.lenght是Java提供的数组的属性,用来获取数组的长度。
数组的遍历可以通过定义遍历数组的方法,然后在调用方法。
增强for循环:
也叫做foreach语句;
语句格式为:
for(元素类型t 元素变量x : 遍历对象obj){
引用了x的java语句;
}
int[] arr = {1,2,3,4,5};
//遍历数组
for(int i : arr) {
System.out.print(i +" ");
}
找出数组的最大值
方法为:
public static int maxPrint(int[] arr){
int max = 0;
for(int i = 0;i<arr.length;i++){
if(arr[i]>max){
max = arr[i];
}
}
return max;
}
找出数组的最下值
public static int minFunction(int[] arr) {
int min = arr[0];
for(int i = 0;i<arr.length;i++) {
if(min>arr[i]) {
min = arr[i];
}
}
return min;
}
public static void method() {
int[] arr = new int[5];
for(int i = 0; i<arr.length;i++) {
arr[i] = (int)(Math.random()*100);
}
//遍历数组
for(int i : arr) {
System.out.print(i +" ");
}
System.out.println();
//得出最小值
int min = arr[0];
for(int i : arr) {
if(min>i) {
min = i;
}
}
System.out.println("最小值是:"+min);
}
将数组逆序
方法为:
public static void reverse(int[] arr){
/* 分析:将最后的数组元素与第一个数组元素调换,然后将第二个数组元素与倒数第二个数组元素调换
第一次调换:
int temp = arr[0];
arr[0] = arr[arr.length-1];
arr[arr.length-1] = temp;
第二次调换:
int temp2 = arr[1];
arr[1] = arr[arr.length-1-1];
arr[arr.length-1-1] = temp2;
这样做代码重复率太高,观察其中规律可以得到,
*/
for(int i = 0; i<arr.length/2;i++){
int temp = arr[i];
arr[i]=arr[arr.length-1-i];
arr[arr.length-1-i] = temp;
}
}
public static void reverse2(int[] arr){
for(int start=0,end = arr.length-1 ;strat<= end;strat++,end--){
int temp= arr[end];
arr[end] = arr[start];
arr[start] = temp;
}
}
数组的查找:
//需求:查找元素在数组中的索引(位置)
public static void main(String[] args){
int[] arr = {12,23,45,67,543};
int index = getIndex(arr,45);
System.out.println(index);
}
//数组的查找功能
public static int getIndex(int[] arr,int value){//value是要查找的元素
int index = -1;
for(int i = 0;i<arr.length;i++){
if(arr[i] == value){
index = x;
}
}
return index;
}
public static int getIndex1(int[] arr, int value){
for(int i = 0 ;i<arr.length;i++){
if(arr[i] == value){
return i;//如果这个方法只有一个返回值,并且它在if、for语句里面必须考虑,如果条件不成立或者for循环完后都没有找的元素,就没有返回值。
}
}
return -1;//如果没有要找的值,返回负数,一般我们返回的是-1;
}
二维数组:
二维数组概念:元素为一维数组的一个数组
格式: 数据类型[][] 变量名 = new 数据类型[m][n];
m:表示有m个一维数组;
n:表示一维数组中有n个元素;
注意以下格式也可表示二维数组:
数据类型 数组名[][] = new 数据类型[m][n];
数据类型[] 数组名[] = new 数据类型[m][n];
例如:
在int[][] arr = new int[3][2];中,
输出二维数组的第一个元素一维数组名称:
System.out.prinln(arr[0]);//这里arr[0]是二维数组中第一个一维数组的名称。
二维数组int[][] arr = new int[3][2];在存储它的内存(栈堆)存放图示:
二维数组的第二种格式:
数据类型[][] 数组名 = new 数据类型[m][];
这个格式的含义是:定义了一个二维数组,里面包含了m个一维数组,一维数组中的元素可以自己定义。可用于里面的一维数组元素不确定的情况下。
比如:
class ArrayFormatTwo{
public static void main(String[] args){
int[][] arr = new int[3][];
arr[0] = {1,2,3};
arr[1] = {2,3,56};
arr[2] = {6,78,0,98,78};
System.out.println(arr[0][1]);
System.out.println(arr[2][3]);
}
}
二维数组的第三种格式(静态初始化):
数据类型[][] 数组名 = {{1,2,3,4},{1,2,4,5,7},{2,3,4,78,9,20}};
二维数组的遍历:
class Test{
public static void main(String[] args){
int arr[][] = {{23,345,78},{98,23,1,5},{54,67,90,34}};
for(int i = 0;i<arr.length;i++){
for(int j = 0 ; j<arr[i].length;j++){
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
}
java基础语法的总结练习:
package error;
/*需求:将随机输入一个个数小于8的整数,要求1、将这个整数倒着输出 7654321
要求2、再将这个整数加上5,其和与10求余得到余数 2 1 0 9, 8, 7, 6
要求3、输出这个余数*/
/*分析:1、定义一个整数 int num = 1234567;想要将这个数倒着输出,整数无法实现。则想到了数组的逆序,
即:怎样将这个整数与数组联系起来?
实现:int ge = num % 10;//ge = 7;
int shi = num/10%10; shi = 6;
int bai = num/10/10%10;bai = 5;
....
int[] arr = new int[8];//整数不超过8;再用定义一个索引来控制数组的遍历,防止空指针异常。
int index = 0;
arr[index] = ge;//arr[0] = 7;
index++;
arr[index] = shi;//arr[1]= 6;
index++;
...
总结知识点:
数组
变量
运算符
方法
选择分支结构
*/
public class distribution {
public static void main(String[] args) {
int num = 1234567;
int index = 0;
int[] arr = new int[8];
while(num>0){//将整数输入到数组中的操作。
arr[index] = num%10;
index++;
num/=10;
}
//再将每个数加上5,其和与10求余得到余数
for (int i = 0; i < index; i++) {
arr[i]+=5;
arr[i]%=10;
}
//输出数组的元素
System.out.print("["+arr[0]+", ");
for (int i = 1; i < index; i++) {
if(i == index -1) {
System.out.print(arr[i]+"]");
break;
}
System.out.print(arr[i]+", ");
}
System.out.println();
}
}
package com.test;
/*
数组Arrays类的包装方法:
1,数组的复制:
Arrays.copyOfRange(copy数组,起始位置,复制的长度);//返回的是一个数组
2,将数组的数字转换成字符串:
Arrays.toString(数组名);//返回的是一个字符串,
3,排序 选择和冒泡(两个相邻的数组元素比较,每上一次的最后元素不作比较)
Arrays.sort(数组名);//无返回值
4,搜索 -- 查看输入的值对应的索引
Arrays.binarySearch(a, 4);//返回的是一个int值;
5,判断数组内容是否相同;
Arrays.equals(数组名,数组名)//返回的是boolean类型的值;
6,填充数组
Arrays.fill(数组名,数值);//返回的是一个数组
*/
import java.util.Arrays;
public class Demo2 {
public static void main(String[] args) {
//Arrays java 自带的数组工具
int[] a = new int[] {1,27,3,41,5};
//数组的复制
int[] b = Arrays.copyOfRange(a,0,5);
printArray(b);
//判断数组内容是否相同
Boolean bool = Arrays.equals(a, b);
System.out.println(bool);
//将数组的数字转换成字符串
String str = Arrays.toString(a);
printArray(a);
//数组的排序
Arrays.sort(a);
printArray(a);
//查看输入的值对应的索引
Arrays.binarySearch(a, 4);
System.out.println((Arrays.binarySearch(a, 27)));
//填充
int[] a3 = new int[5];
Arrays.fill(a3,1);
printArray(a3);
}
//输出数组的方法printArray();
public static void printArray(int[] arr) {
for(int i = 0;i<arr.length;i++) {
if(i == 0) {
System.out.print("["+arr[i]);
}else {
System.out.print(" "+arr[i]);
}
}
System.out.println("]");
}
}