Java基础(变量、数据类型、运算符、分支结构、循环结构、数组、方法)

Java基础

1.1 变量

1.1.1 简介

变量是一个代词,指代在计算机的内存中的一块空间,用来存储程序在运行中所需要的数据。

1.1.2 命名规则 

  1. 只能包含字母、数字、_$,并且不能以数字开头
  2. 不能使用关键字/保留字(是关键字的一种,但是占着不用)51+2
  3. 严格区分大小写(对大小写敏感)
  4. 可以是中文、日文、韩文等命名,但不建议,有可能乱码
  5. 建议:英文的见名知意、驼峰命名法,不要使用拼音。

1.1.3 声明

变量的声明指的是在内存中开辟一块指定大小的内存空间,默认还没有存数据。

语法结构:数据类型 变量名;

// 声明了一个int类型变量num
int num;
// 声明了三个int类型变量a、b、c
int a, b, c;

1.1.4 初始化

变量的初始化指的是对变量的第一次赋值。

语法结构:数据类型 变量名 = ;

1.声明同时初始化
// 声明变量num,同时赋值为250
int num = 250;
2.先声明再初始化
// 声明变量num
int num;
// 给num赋值为250
num = 250;
3.同时声明多个变量(用得较少)
// 同时声明变量a、b、c
int a, b, c;
// 同时声明变量a、b、c,并分别赋值为100、200、300
int a=100, b=200, c=300;

1.1.5 访问(操作)

  1. 变量在使用之前必须要声明并初始化;
  2. 变量的操作必须与类型匹配。

1.2 数据类型   

1.2.1 简介

基本数据类型也叫原生数据类型Java保留了C语言中的8个基本数据类型,为了计算方便,速度快,但是不能参与面向对象开发。

包装类S

1.2.2 整数相关

  1. byte : 字节型,1个字节(8)-128 ~ 127用得一般  
  2. short : 短整型,2个字节(16)-32768 ~ 32767少到几乎不用
  3. int : 整型,4个字节(32)-2^31 ~ 2^31-1最常用

- Java中整数直接量默认为int类型,如: 12325010000

- 两个int类型的变量操作,结果还是int类型,小数位无条件舍弃

  1. long : 长整型,8个字节(64)-2^63 ~ 2^63-1用得一般

- long类型的直接量,要在整数后面加lL,如: 123L250L

- 如果要计算超出了long范围的时候,可以使用BigInteger

1.2.3 小数相关

  1. float : 浮点型,4个字节(32)-2^31 ~ 2^31-1少到几乎不用

- float类型的直接量,要在小数后面加fF,如: 3.14F

  1. double : 双精度浮点型,8个字节(64)-2^63 ~ 2^63-1最常用

- Java中小数直接量默认为double类型,如: 3.146.18

- 有可能会出现舍入误差,精确运算时要慎用,(因为10进制与2进制之间转换时有可能会损失精度)

- 要做小数的精确计算时,可以使用BigDecimal

1.2.4 其他类型

  1. char : 字符型,2个字节(无符号16)0 ~ 65535

- char类型的直接量,需要放在’’单引号中,单引号中有且仅有1个字符

- 使用Unicode编码格式,实质上是整数,即char对应的码,如: A->65a->97

- ”Java程序员在内存中占多少个字节?14  

  1. boolean : 布尔型,1个字节(8)false/true

 

1.2.5 附:面试题

  1. Java中的原生数据类型有哪些?各自的范围是多少?

1.3 基本数据类型的转换

1.3.1 自动类型转换,从小类型到大类型

byte --> short --> int --> long --> float --> double  -->   char

1.3.2 强制类型转换,从大类型到小类型强转,有可能发生精度丢失、溢出。向下造型

double d = 3.14;

//float f = d; //编译错误,大类型不能直接赋值给小类型

float f = (float) d; //将d中的数据强转成float类型

int i = (int) d; //强制转换,i=3,精度丢失

 

long l = 200;

byte b = (byte) l; //强制转换,溢出了

1.3.3 附:面试题

  1. 下面的代码编译是否正确?
short s1 = 10;

short s2 = 20;

s1 = s1 + s2; //编译错误,因为short类型的运算结果自动变成int类型

1.4 运算符

1.4.1 算术运算符 + - * / % ++ --

% : 取余/取模,两个数相除取余数,如: 4/3=11+  5/3求模      

++ : 自增,变量自身加1

++a 先运算后赋值、  a++先赋值后运算

int a = 11;

// 先赋值后加1:先把a变量的值10赋给a++表达式(a++=10),然后a变量自身再加1(a=11

int b = a++;

Int b=++a;

System.out.println(a); //11

System.out.println(b); //10

 
int x = 10;

// 先加1后赋值:x变量先自身加1(x=11),然后再将x变量的值11赋给++x表达式(++x=11)

int y = ++x;

System.out.println(x); //11

System.out.println(y); //11

 
int c=5;

int f=2;//3

int d=f++;

System.out.println(f);//3

-- : 自减,变量自身减1

 
int a = 10;

// 先赋值后减1:先把a变量的值赋给a--表达式(a--=10),然后a变量自身再减1(a=9

int b = a--;//先赋值再减减

System.out.println(a); //9

System.out.println(b); //10

int x = 10;

// 先减1后赋值:x变量先自身减1(x=9),然后再将x变量的值9赋给--x表达式(--x=9

int y = --x;//先运算后赋值

System.out.println(x); //9

System.out.println(y); //9

1.4.2 关系运算符  >  <  >=  <=  ==  !=

 

System.out.println( 10 > 5 ); //true

System.out.println( 10 < 5 ); //false

System.out.println( 10 >= 10 ); //true

System.out.println( 10 <= 10 ); //true

System.out.println( 10 == 10 ); //true      

System.out.println( 10 != 10 ); //false

 

- 关系运算符的结果为boolean类型

1.4.3 逻辑运算符  &&  ||  !

 && : 逻辑与/短路与,两边表达式都为true,结果才为true,若左边的表达式为false时会发生短路(右边的表达式不再执行了)。

|| : 逻辑或/短路或,只要一边表达式为true,结果就为true,若左边的表达式为true时会发生短路(右边的表达式不再执行了)。

! : /取反,非真true则假false,非假false则真true

// 判断是否为闰年:1.年份能被4整除并且不能被100整除,2.年份能直接被400整除

int year = 2020;  3200

boolean b = (year%4==0 && year%100!=0) || year%400==0;

System.out.println(“是否为闰年?” + b);

- 逻辑运算符一般配合关系运算符来使用

- 逻辑运算符的结果为boolean类型

1.4.4 赋值运算符  =  +=  -=  *=  /=  %=

= : 普通赋值运算符

+=  -=  *=  /=  %= : 扩展赋值运算符

 

int a = 10;

a += 20; //相当于: a = a + 20;

 

- 扩展赋值运算符默认有类型转换的特点

 

short s1 = 10;

short s2 = 20;

s1 = s1 + s2; //编译错误,short类型运算后的结果是int类型,int不能直接赋给short

 

s1 += s2; //编译通过,相当于: s1 = (short) (s1 + s2);

 

1.4.5 三目运算符

三目运算符也叫三元运算符,因为它是由3个表达式组成的。

语法结构:boolean表达式1 ? 表达式2 : 表达式3;

- 三目运算符的执行过程:

  1. 先判断boolean表达式1
  2. boolean表达式1true,执行:冒号左边的表达式2,否则执行:冒号右边的表达式3 //不建议使用,使用if

 

// 求两个数中的最大值

int a = ?;

int b = ?;

int max = a > b ? a : b;

System.out.println(max);

 

- 三目运算符可以嵌套,嵌套之后使代码结构不清晰,但是一般不用。

1.4.6 字符串连接符

+ 即可以用来做算数加法运算,也可以用来做字符串的拼接运算。

  1. + 左右两边都是数字类型时,默认做加法运算;
  2. + 左右两边只要有字符串类型时,默认做字符串拼接运行;
  3. 字符串拼接后,结果还是字符串;

 

int a = 250;

String s1 = “hello”;

String s2 = s1 + a; // “hello”+250 => “hello250”

 

String str = 5 + 7 + “abc” + 7 + 5;

System.out.println(str); //”12abc75”

 

1.4.7 位运算符(扩展)

位运算符是针对二进制运算的,常见的位运算符有以下这些:

  1. & : 位与,两边都是1,结果才是1
  2. | : 位或,两边都是0,结果才是0
  3. ~ : 位反,~0=1~1=0
  4. ^ : 位异或,一边为1一边为0时,结果才是1
  5. >> : 位有符号右移,将二进制整体向右边移动,前面补0,保留符号位(/)
  6. << : 位有符号左移,将二进制整体向左边移动,后面补0,保留符号位(/)
  7. >>> : 位无符号右移,将二进制整体向右边移动,前面补0,不保留符号位,移完后都是正数

1.4.8 附:面试题

  1. & 和 && 的区别?

& && 都可以用来做逻辑运算

a&是位与运算符,&&是逻辑与运算符

b&不会发生短路,&&是会发生短路的

 

 

2. 使用最有效的方式计算 8/4 的结果?

8 >> 2

00001000 >> 2 = 00000010

1.5 分支结构

Java编程语言中有三种语法结构,分别是:顺序结构、分支结构、循环结构。

分支结构指的是根据条件的判断去决定是否执行某段代码,简单的说就是可以选择性的去执行某些代码。

1.5.1 单路分支

单路分支是指如果条件成立了就去执行指定的代码,否则就不执行。

语法结构:if(条件) { 条件成立时执行的代码... }

int price = ?;
if (price >= 500) {
    System.out.println(“打8折!”);
}

//超市、
特殊写法:
if(price >=500)
System.out.println(“打8折!”); //不常用

1.5.2 双路分支

双路分支是指如果条件成立了就去执行指定的第一段代码,否则就去执行指定的第二段代码。场景:一个条件做两件事情

语法结构:

if(条件) { //true/false

第一段代码... true

}else{

第二段代码... flase

}

// 判断年份是否为闰年

int year = 2020;

if (year%4==0 && year%100!=0 || year%400==0) {

    System.out.println(year + “是闰年!”);

} else {

    System.out.println(year + “不是闰年!”);

}

1.5.3 多路分支(嵌套分支)

多路分支是指在多个条件的判断下,去执行其中条件成立指定的代码。场景:多个条件做多件事情,确定一个范围

语法结构:

if (条件1) {

  代码块1

} else if(条件2) {

  代码块2

} else if(条件n) {

  代码块n

} else {

  代码块else

}

 

// 其实,上面的代码是下面嵌套代码的简写

if (条件1) {

  代码块1

} else {

if(条件2) {

      代码块2

} else {

if(条件n) {

          代码块n

} else {

          代码块else

}

}

}

 

// 成绩等级判断

int score = ?;

 

if (score >= 90) {

    System.out.println(“A-优秀”);

} else if (score >= 80) {

    System.out.println(“B-良好”);

} else if (score >= 70) {

    System.out.println(“C-中等”);

} else if (score >= 60) {

    System.out.println(“D-及格”);

} else {

    System.out.println(“E-不及格”);

}

 

1.5.4 switch case

switch case 也是用来作为多路分支,优点是速度快,缺点是不够灵活。场景:确定值的时候(不是一个范围)

语法结构:

 

switch(表达式) {

  case 1:

    代码块1;

    break;

  case 2:

    代码块2;

    break;

  case n:

    代码块n;

    break;

  default:

    代码块default;

}

 

- switch括号中的表达式结果只能是intString类型。

- case 后面的值一定要是直接量或常量,不能是变量。

- break 用来中断switch语句,也就是不要再执行break后面的代码;注意:如果没有break的话,case将会出现穿透的效果(会一路执行到switch内部代码的最后,或是一路执行到后面遇到的break为止)。

 

// 模拟取款机程序

int cmd = ?;

 

switch (cmd) {

  case 1:

    System.out.println(“查询余额”);

    break;

  case 2:

    System.out.println(“转账”);

    break;

  case 3:

    System.out.println(“取款”);

    break;

  default:

    System.out.println(“输入有误”);

}

 

 

 

1.6 循环结构

循环指的是反复/重复去执行一段相同或相似的代码。

1.6.1 while

语法结构:

 

while(条件) {

    循环体代码块

}

 

执行流程:

条件成立,就会循环执行循环体代码块,直到条件不成立为止。

应用场景:

当咱们不知道要循环多少次时,也就是说循环次数不确定时。

1.6.2 do while

语法结构:

 

do {

    循环体代码块

} while(条件);

 

执行流程:

1、先执行一次循环体代码块

2、当条件成立,则继续循环执行循环体代码块,直到条件不成立为止。

应用场景:

当咱们要先执行一次循环体代码块,再进行循环条件的判断时。

在实际的开发中,do while循环用的较少。

1.6.3 for

语法结构:

 

for (表达式1; 表达式2; 表达式3) {

    循环体代码块

}

 

说明:

  1. 表达式1 - 循环变量的初始化
  2. 表达式2 - 循环的条件
  3. 表达式3 - 循环变量的改变(注:应该要向着循环结束去改变)

执行流程:

  1. 先执行表达式1,进行循环变量的初始化操作,注:只执行一次
  2. 再执行表达式2,进行循环条件的判断

1) 若条件成立,则执行循环体代码块

2) 若条件不成立,则结束循环

  1. 再执行表达式3,进行循环变量的改变
  2. 依次第2.和第3.步循环执行

应用场景:

当循环次数固定时,建议使用for循环。

1.6.4 循环的关键字

break 是中断的意思,在循环中使用时,可以使当前循环结束。注:break只能结束一层循环。

continue 是继续的意思,用在循环中,跳过本次循环continue后面的代码,从而进入下一次循环。

 

int sum = 0;

for(int i = 0; i < 10; i++) {

    if(i % 2 == 0){

        continue;

}

sum += i;

}

 

 

 

int sum = 0;

for(int i = 0; i < 10; i++) {

    if(i == 5){

        break;

}

sum += i;

}

System.out.println(sum);

 

1.6.5 循环的嵌套

循环的嵌套指的是在循环中可以嵌套另一个循环,可以多层嵌套,但是开发中循环的嵌套最好不要超过3层。

 

// 九九乘法表

for(int i = 1; i <= 9; i++) { //循环9次,控制行数

    for(int j = 1; j <= i; j++) { //控制列数,列数跟随行数底层而增加的

        System.out.print( i + “*” + j + “=” + (i * j) );

}

System.out.println();

}

 

说明:

外层循环执行一次,它的内层循环要执行完一轮。

1.7 数组

1.7.1 数组的简介

  1. 数组是指一组数据的集合,数组中的每个数据称作为元素
  2. 数组是一种线性表数据结构,它用一组连续的内存空间,来存储一组具有相同类型的数据。
  3. 同一个数组中存放的元素的类型必须要一致。
  4. Java中,数组是一种引用数据类型

1.7.2 数组的声明

声明数组是指告诉Java数组的类型是什么。

// 1.中括号[]写在类型的后面,Java中推荐这种写法

int[] arr;

 

// 2.中括号[]写在变量名的后面

int arr[];

 

int[][] arr;

int arr[][];

int[] arr[];

1.7.3 数组的初始化

语法结构:

// 先声明数组

int[] arr;

// 对数组默认初始化

arr = new int[10];

上述代码相当于在内存中定义了10int类型的变量,第1个变量表示为arr[0],第2个变量表示为arr[1],以此类推,第10个变量表示为arr[9]。其中的01,…,9称为数组的下标/索引,下标从0开始,到数组的长度-1”结束。

当然,除了上面初始化数组的方式外,还可以像下面这样:

// 声明和初始化写在一起,数组中默认每个元素的初始化值为0

int[] arr = new int[10];

 

// 声明和初始化一起,但是手动指定初始化的值

int[] arr = {1, 2, 3};

 

// 声明和初始化一起,手动指定好初始化的值,注意:[]中括号中不能再指定长度

int[] arr = new int[]{1, 2, 3};

 

 

问题:int[] arr = {1,2,3} int[] arr = new int[]{1,2,3} 的区别?

 

int[] arr = {1,2,3} 只能声明和初始化写在一起,不能分开写,如:

int[] arr;

arr = {1,2,3}; //编译错误的

 

int[] arr = new int[]{1,2,3} 可以声明和初始化写在一起,也可以分开,如:

int[] arr;

arr = new int[]{1,2,3}; //编译成功

1.7.4 数组的访问

通过下标/索引来访问元素,数组提供了一个length属性,来获取数组的长度(元素的个数)

int[] arr = {1, 4, 7, 8};

System.out.println(arr.length); //打印数组的长度:4

arr[0] = 100; //arr中的第1个数赋值为100,此时:[100, 4, 7, 8]

System.out.println(arr[3]); //输出arr中的最后一个数:8

System.out.println(arr[arr.length-1]); //灵活的输出arr中最后一个元素

arr[4] = 88; //错误的,下标越界/超范围,ArrayIndexOutOfBoundsException

1.7.5 数组的遍历

遍历是指对数组中所有元素的访问,依次对数组中每个元素访问一次。

  1. 顺序遍历

int[] arr = {1, 4, 7};

 

for(int i = 0; i < arr.length; i++){

int a = arr[i]; //arr[0], arr[1], arr[2]

System.out.println(a); 

}

  1. 倒序遍历

int[] arr = {1, 4, 7};

 

for(int i = arr.length - 1; i >= 0; i--){

System.out.println(arr[i]); //arr[2], arr[1], arr[0]

}

  1. 增强版for循环遍历

int[] arr = {1, 4, 7};

 

// a表示每次循环从数组中取出的那个元素,arr表示要遍历的数组

for(int a : arr){

    System.out.println(a);

}

1.7.6 数组的排序

  1. 自带排序

int[] arr = {3, 6, 9, 2, 5, 8, 1, 4, 7};

 

// Arrays.sort(T[] arr) 默认按照升序(从小到大)来排序的

java.util.Arrays.sort(arr);

 

System.out.println(Arrays.toString(arr)); //打印排序后的数组,[1, 2, 3, 4, 5, 6, 7, 8, 9]

  1. 冒泡排序(笔试)

int[] arr = {3, 6, 9, 2, 5, 8, 1, 4, 7};

 

for(int i=0; i<arr.length-1; i++){ //控制趟数

for(int j=0; j<arr.length-1-i; j++){ //控制每趟的次数

//如果当前元素比后一个元素大,则交换位置

if(arr[j] > arr[j+1]){

int temp = arr[j];

arr[j] = arr[j+1];

arr[j+1] = temp;

}

}

}

 

System.out.println(Arrays.toString(arr)); //打印排序后的数组

1.7.7 数组的工具类

Java中提供了java.util.Arrays工具类,可以对数组进行排序、检索、转换、输出等操作。

Arrays.sort(arr); //对数组进行排序

int index = Arrays.binarySearch(arr, key); //对数组进行二分查找,注:数组中的元素一定是升序的

String str = Arrays.toString(arr); //将数组转换为字符串

int[] newArr = Arrays.copyOf(arr, len); //扩容/缩容 数组

1.8 方法

1.8.1 方法的简介

方法也称为函数/过程,封装的一段特定的逻辑功能、有名字的代码块。

方法可以使程序结构清晰、便于代码的重复使用

1.8.2 方法的定义

语法结构:

修饰符 返回值类型 方法名 ( [参数类型 参数名1, 参数类型 参数名2, ...] ) {

方法体

[return 返回值;]

}

上述代码的语法格式具体说明如下:

- 修饰符:用于限定方法的声明,常见的有访问控制修饰符、静态修饰符、最终修饰符 等等。

- 返回值类型:用于限定方法返回值的数据类型,为了告诉调用者知道要用什么类型来接收返回结果。

- 参数类型:用于限定调用方法时传入参数的数据类型。

- 参数名:是一个变量,用于接收调用方法时传入的数据。

- return 关键字:用于结束方法以及返回方法指定类型的值。

- 返回值:被return语句返回的数据,该值会返回给调用者。

方法中的[参数类型 参数名1, 参数类型 参数名2, ...]”称为参数列表,表示方法在调用时需要接收的参数,如果方法不需要接收任何参数,则参数列表为空,即()括号内不写任何内容。

如果方法中没有返回值,那么返回值类型要声明为void,方法中的return语句可以省略。

例如:

//无返回值无参数的方法

public static void sayHi() {

System.out.println("Hi");

}

 

//有返回值有参数的方法

public static int sum(int a, int b) {

int result = a + b;

return result;

}

 

//封装冒泡排序算法,方便重复调用

public static void bubbleSort(int[] arr) {

for(int i=0; i<arr.length-1; i++){ //控制趟数

for(int j=0; j<arr.length-1-i; j++){ //控制每趟的次数

//如果当前元素比后一个元素大,则交换位置

if(arr[j] > arr[j+1]){

int temp = arr[j];

arr[j] = arr[j+1];

arr[j+1] = temp;

}

}

}

}

- 什么时候方法要定义参数?

当方法中要使用到的数据,但是又不能在方法中写死,那么这时就可以把这些数据先定义为方法的参数,让调用者在调用方法时再具体传递过来,参数可以使得方法变得更加灵活。

- 什么时候方法要定义具体返回值类型?

当方法中逻辑计算完成之后,要返回计算的结果给调用者时,那么就得定义具体的返回值类型。

1.8.3 方法的调用

- 无参无返回值方法的调用

方法名();

System.out.println();

- 有参无返回值方法的调用

方法名(参数值..);

System.out.println(250);

- 无参有返回值方法的调用

数据类型 变量名 = 方法名();

double num = Math.random();

- 有参有返回值方法的调用

数据类型 变量名 = 方法名(参数值..);

double sqrt = Math.sqrt(4);

 good luck!

 

 

 

  1. & 和 && 的区别?
原文地址:https://www.cnblogs.com/hxun/p/14098583.html