Java基础入门教程-基础语法
Java基础知识、web开发用到的前端知识以及常用的各种框架和中间件,涵盖计算机基础、数据库、部署工具以及代码风格和规范的全栈知识体系
一、基础语法
1、第一个Java程序
public class Hello{
//定义一个名为Hello的类(
public static void main(String[] args){
//main入口
System.out.println("Hello World");
//打印输出Hello World
}
}
2、数据类型
- 常量:在程序的执行过程中,其值不会发生改变的量(数据)。
- 变量:就是内存中的存储空间,空间中存储着经常发生改变的值。
- 基本数据类型
- 引用数据类型:除了上述8种基本数据类型,其余的都是引用数据类型(引用类型存放在堆里,基本类型存放在栈里)
3、键盘录入
这在正式开发中并不常用,适用于学习阶段或者调试程序。
- 目的:为了让数据更加灵活
- 使用步骤
- 导包:
import java.util.Scanner;
(需要写在class上面) - 创建对象:
Scanner sc = new Scanner(System.in);
- 使用变量接收数据:
int i = sc.nextInt();
- 导包:
import java.util.Scanner;
//导包
public class input{
//创建input类
public static void main(String[] args){
//主入口
Scanner scan = new Scanner(System.in);
//创建对象
int a = scan.nextInt();
//使用变量接收数据
System.out.println(a);
//打印输出数据
}
}
除了nextInt()
接收int类型数据,还可以使用nextLine()
、next()
等方法接收字符串等数据
4、标识符
就是给类、方法、变量等起名字的符号
定义规则
- 由数字、字母、下划线(_)和美元符($)组成。
- 不能以数字开头
- 不能是关键字
- 严格区分大小写
常见命名约定
- 小驼峰命名法:方法、变量约定1:标识符是一个单词的时候,首字母小写 范例1:
name
约定2:标识符由多个单词组成的时候,第一个单词首字母小写,其他单词首字母大写 范例2:firstName
- 大驼峰命名法:类约定1:标识符是一个单词的时候,首字母大写 范例1:
Student
约定2:标识符由多个单词组成的时候,每个单词首字母都大写 范例2:GoodStudent
5、类型转换
隐式转换:将数据类型中,取值范围小的数据,给取值范围大的类型赋值,可以直接赋值
int a = 10;
//int占4字节
double b = a;
//double占8字节
小的给大的,可以直接给 小的数据和大的数据类型运算,小的会先提升为大的数据类型再进行运算
byte short char 这三种数据在运算的时候,无论是否有更高的数据类型,都会提升为int,然后再进行运算
强制转换:把一个表示数据范围大的数值或者变量赋值给另一个表示数据范围小的变量 格式:目标数据类型 变量名 = (目标数据类型)值或者变量;
int a = 10;
//int 4字节
byte b = (byte)a;
//byte 1字节
int c = (int)88.88;
强制类型转换,有可能会发生精度损失
精度损失:简单理解,将容积为8升的水倒入容积为4升的桶中,多出的水会洒掉
类型转换案例
public class Test{
public static void main(String[] args){
byte a = 3;
//①
byte b = 4;
//②
byte c = a + b;
//③
byte d = 3 + 4;
//④
}
}
③中错误,在byte short char运算时,会直接提升为int,然后再进行运算; ④正确:Java存在常量优化机制,3和4是两个常量,会在编译的时候让3和4进行相加,然后判断7是否在byte的取值范围内
6、运算符
对常量或者变量进行操作的符号
表达式:用运算符把常量或者变量连接起来符合Java语法的式子就可以称为表达式。 不同运算符连接的表达式体现的是不同类型的表达式。
int a = 10;
int b = 20;
int c = a + b;
算术运算符:加(+)、减(-)、乘(*)、除(/)、取余(%)
- 在使用除法时需要注意,5/2的结果是2而不是2.5。想要得到小数必须有浮点数参与运算
- 字符之间相加时,字符会根据ASCII码值提升为int类型进行运算(0–48 a–97 A–65)
- 在
+
操作中,如果出现了字符串,就是连接运算符,否则就是算术运算符,当连续进行+
操作时,从左到右逐个执行
int a = 1;
char b = 'a';
System.out.println(a + b);
//输出98
System.out.println("java" + 666);
//java666
System.out.println(1 + 99 +"java");
//100java
System.out.println("5+5=" + 5 + 5);
//5+5=55
System.out.println("5+5=" + (5 + 5));
//5+5=10
自增自减运算符:自增(++)、自减(–)
- 单独使用时,
++
和--
在前或者在后时结果都一样 - 当参与其他操作时,在前则先自增(自减)后进行操作;在后则表示先进行相应操作后进行自增(自减)
- 只能操作变量,不能操作常量
赋值运算符:赋值(=)、加后赋值(+=)、减后赋值(-=)、乘后赋值(*=)、除后赋值(/=)、取余后赋值(%=)
int a = 10;
a += 20;
//a = a + 20
System.out.println(a);
//30
注意:扩展运算符底层会自带强制类型转换的功能
关系(比较)运算符:等于(==)、不等(!=)、大于(> )、大于等于(> =)、小于()、小于等于(=)
- 返回结果只有true或者false
逻辑运算符
- & (与):并且,全真则真,一假则假
- |(或):或者,全假则假,一真则真
- !(非):取反,真假假真
- ^(异或):两同为假,不同为真
- 短路逻辑运算符& & (短路与):作用和& 相同,但有短路效果||(短路与):作用和|相同,但有短路效果
逻辑短路:&
&
遇到false直接为false,不执行后面代码;
||
遇到true则直接为true,不执行后续代码
三元运算符
- 格式:
关系表达式 ? 表达式1 : 表达式2;
- 执行流程首先计算关系表达式的值 若为true则取表达式1的值 若为false则取表达式2的值
7、流程控制
通过一些语句,来控制程序的执行流程
顺序结构语句:程序中最简单最基本的流程控制,没有特定的语法结构,按照代码的先后顺序依次执行,程序中大多数代码都是这样的
7.1. if语句
格式1
if(关系表达式){
语句体1;
}
else{
语句体2;
}
执行流程
- 首先计算关系表达式的值
- 如果关系表达式的值为true则执行语句体1
- 如果关系表达式为false就执行语句体2
- 继续执行后续代码
import java.util.Scanner;
public class a{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的年龄:");
int age = sc.nextInt();
if(age >
= 18){
System.out.println("您已成年,可以进入");
}
else{
System.out.println("对不起,您未成年,不能进入");
}
}
}
如果if语句中的语句体只有一条,那么大括号{ } 可以省略不写,但是不建议,容易混淆 if语句小括号后面不要写分号;
格式2(多条件判断)
if(判断条件){
语句体1;
}
else if(判断条件2){
语句体2;
}
...
else{
语句体n+1;
}
import java.util.Scanner;
public class a{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的成绩:");
int score = sc.nextInt();
if(score >
= 90 &
&
score = 100){
System.out.println("优秀");
}
else if(score >
= 80 &
&
score 90){
System.out.println("良好");
}
else if(score >
=60 &
&
score 80){
System.out.println("及格");
}
else if(score 60 &
&
score >
= 0){
System.out.println("不及格");
}
else{
System.out.println("请输入正确的成绩!");
}
}
}
7.2. switch语句
格式
switch(表达式){
case 值1:
语句体1;
break;
case 值2;
语句体2;
break;
....
default:
语句体n+1;
break;
}
格式说明
- 表达式(将要被匹配的值)取值为byte、short、int、char、枚举(jdk5)、String(jdk7)
- case:后面跟的是要和表达式比较的值(被匹配的值)
- break:表示中断,结束的意思,用来结束switch语句
- default:表示所有的情况都不匹配的时候,就执行该处的内容,和if语句的else相似
case穿透
- 现象:当开始case穿透,后续的case就不会具有匹配的效果,内部的语句都会执行。直到看见break,或者将整体switch语句执行完毕,才会结束
- 应用场景:当多个case语句出现重复现象,就可以考虑使用case穿透来优化代码
7.3. for循环
推荐在明确循环次数时使用
格式
for(初始化语句;
条件判断语句;
条件控制语句){
循环体语句;
}
执行流程
- 执行初始化语句
- 执行条件判断语句,看其结果是true还是false
- 如果是false,循环结束
- 如果是true,循环继续
- 执行循环体语句
- 执行条件控制语句
- 回到第2步继续循环
案例
//在控制台输出1-5
for(int i = 1;
i = 5;
i++){
System.out.println(i);
}
//求1-5的数据和
int sum = 0;
for(int i = 1;
i = 5;
i++){
sum += i;
}
System.out.println(sum);
//求1-100的偶数和
int sum = 0;
for(int i = 1;
i = 100;
i++){
if(i % 2 == 0){
sum += i;
}
}
System.out.println(sum);
//输出所有的水仙花数
//水仙花数:是一个三位数,个位、十位、百位的数字立方和等于原数
for(int i = 100;
i = 999;
i++){
int sum;
int a = i % 10;
int b = i / 10 % 10;
int c = i / 100;
sum = a * a * a + b * b * b + c * c * c;
if(sum == i){
System.out.println(i);
}
}
System.out.print()
为同行打印,不换行 System.out.println()
自带换行效果,类似于html中的块级元素,独占一行。括号内无内容时可以当作换行符来使用
7.4. while循环
不明确循环次数时推荐while
格式
while(条件判断语句){
循环体语句;
条件控制语句;
}
int i = 1;
while(int i = 100){
System.out.println(i);
i++;
}
7.5. do…while循环
使用较少
格式
do{
循环体语句;
条件控制语句;
}
while(条件判断语句);
三种循环的区别:
- for循环和while循环先判断条件是否成立,然后决定是否执行循环体(先判断后执行)
- do…while循环先执行一次循环体,然后判断条件是否成立,是否继续执行循环体(先执行后判断)
- for循环语句中所控制的自增变量,在循环结束后,就不能再次被访问到了
7.6. 死循环
//for
for(;
;
){
循环体语句;
}
//while
while(true){
循环体语句;
}
//do...while
do{
循环体语句;
}
while(true);
- 应用场景:
例如:键盘录入一个1-100之间的整数(用户可能出现误操作现象)
while(true){
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
if(a >
= 1 &
&
a = 100){
b
}
}
for循环中,条件语句可以省略,但是;
不能省略
7.7. continue与break关键字
- continue:跳过某次循环内容,继续开始下一层循环,只能在循环中使用
- break:跳出整个循环,终止循环体内容的执行,只能在循环和switch中使用
- 标号:可以给语句块加标号赋予它们名称,标号位于语句之前。标号只能被continue和break引用。
public class Test{
public static void main(String[] args){
int n = 1;
lo: //标号
while(true){
switch(n){
case 1:
System.out.println("1");
break lo;
//通过标号,这里的break将结束外层while循环
}
}
}
}
语句前只允许加一个标号,标号后面不能跟大括号。通过用break后加标号对处于标号中的语句进行控制。往往标号后是for、while、do-while等循环
8、Random
作用:用于产生一个随机数
使用步骤
- 导包
import java.util.Random;
- 创建对象
Random r = new Random();
- 获取随机数
int number = r.nextInt(10); //获取数据的范围:[0,10),包括0,不包括10 int number = r.nextInt(10) + 1; //获取数据的范围:[1,10],包括1,也包括10
猜数字案例
import java.util.Random;
import java.util.Scanner;
public class a{
public static void main(String[] args){
Random r = new Random();
int ran = r.nextInt(100) + 1;
while(true){
System.out.print("请输入您猜的数字:");
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
if(n >
ran){
System.out.println("猜大了~~");
}
else if(n ran){
System.out.println("猜小了~~");
}
else {
System.out.println("猜恭喜你,猜对了,答案就是" + ran);
break;
}
}
}
}
除了使用Random这个类,Math类中也有生成随机数的方法
9、数组
数组(array):是一种容器,用来存储同种数据类型(或者比它所占字节小的)的多个值
格式
//1.数据类型[] 变量名 【最常用】
int[] array;
//2.数据类型 变量名[]
int array[];
9.1. 初始化
在Java中,数组必须先初始化,才能使用 所谓初始化,就是在内存中,为数组容器开辟空间,并将数据存入容器的过程
动态初始化:初始化时只指定数组长度,由系统为数组分配初始值
- 只明确元素个数,不明确具体数值时推荐使用
- 格式:
数据类型[] 变量名 = new 数据类型[数组长度];
- 范例:
int[] arr = new int[3];
- 注意:打印数组变量名,输出的是数组在内存中的地址值
静态初始化:初始化时就可以指定数组要存储的元素,系统还会自动计算出该数组的长度
- 需求中明确了具体数据,直接静态初始化即可
- 格式:
数据类型[] 变量名 = new 数据类型[]{ 数据1,数据2,数据3,....} ;
- 范例:
int[] arr = new int[]{ 1,2,3} ;
- 简化格式:
int[] arr = { 1,2,3} ;
内存分配
Java程序在运行时,需要在内存中分配空间,为了提高效率,就对空间进行了不同区域的划分 每一片区域都有特定的处理数据的方式和内存管理方式
- 栈内存:方法运行时,进入的内存,局部变量都存放于这块内存当中
- 堆内存:new出来的内容(引用类型)就会进入堆内存,并且会存在地址值
- 方法区:字节码文件加载时进入的内存
- 本地方法栈:调用操作系统相关资源
- 寄存器:交给CPU去使用
9.2. 数组元素访问
- 数组内存地址的访问:
数组名
- 数组内部保存的数据的访问:
数组名[索引]
- 索引从0开始,是连续的,逐一增加
- 数组在创建完毕后,没有赋值也能取出,取出的为默认值
默认值
- 整数——0
- 浮点数——0.0
- 布尔——false
- 字符——空字符
- 引用数据类型——null
数组遍历:将数组中所有的元素取出来
- 动态获取数组元素个数:
数组名.length
int arr = {
1,2,3,4,5,6,7,8,9}
;
for(int i = 0;
i = arr.length;
i++){
System.out.println(arr[i]);
}
注意:遍历是指取出数据的过程,不要局限的理解为:遍历就是打印
9.3. 数据常见操作
获取最值
- 定义一个变量,用于保存最大值(或最小值)
- 取数组中的第一个值作为变量的初始值(假设第一个值就是最大/小值)
- 与数组中的剩余数据逐个对比
int[] arr = {
1, 2, 3, 4, 5, 6, 7000, 8, 919}
;
int max = arr[0];
for(int i = 0;
i arr.length;
i++){
if(arr[i] >
max) max = arr[i];
}
System.out.println("最大值为:" + max);
数组元素求和
import java.util.Scanner;
public class test{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int[] arr = new int[];
int sum = 0;
for(int i = 0;
i arr.length;
i++){
System.out.print("请输入第" + (i+1) + "个数值:");
int n = sc.nextInt();
sum += n;
}
System.out.println("数组内的元素的和为:" + sum);
}
}
数组基本查找
int[] arr = {
19, 28, 37, 46, 50}
;
Scanner sc = new Scanner(System.in);
System.out.print("请输入您要查找的数据:");
int n = sc.nextInt();
for(int i = 0;
i arr.length;
i++){
if(arr[i] == n){
System.out.println("您要查找的数据索引为:" + i);
break;
}
}
9.4. 数组的高级操作
9.4.1. 二分查找
- 前提:数组的元素按照大小、顺序排列
- 每次去掉一半的查找范围
步骤
- 定义两个变量,表示要查找的范围。默认min=0,max = 最大索引
- 循环查找,但是min = max
- 计算出mid的值
- 判断mid位置的元素是否为要查找的元素,如果是直接返回对应索引
- 如果要查找的值在mid左半边,那么min值不变,max = mid – 1,继续下次循环查找
- 如果要查找的值在mid右半边,那么max值不变,max = mid + 1,继续下次循环查找
- 当min >
max时,表示要查找的元素在数组中不存在,返回-1
public class MyBinarySearchDemo{ public static void main(String[] args) { int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} ; int number = 10; int index = binarySearchForIndex(arr, number); System.out.println(index); } private static int binarySearchForIndex(int[] arr, int number) { // 定义查找的范围 int min = 0; int max = arr.length - 1; // 循环查找 min = max while (min = max) { // 计算中间位置 int mid = (min + max) > > 1; // 右移一位,也是除以二的意思
// mid指向的元素 > number if (arr[mid] > number) { // 表示要查找的元素在左边 max = mid - 1; } // mid指向的元素 number else if (arr[mid] number) { // 表示要查找的元素在右边 min = mid + 1; } else { // mid指向的元素 == number return mid; } } // 如果min大于了max就表示元素不存在,返回-1 return -1; } }
9.4.2. 冒泡排序
排序:将一组数据按照固定的规则进行排列
冒泡排序:相邻的数据两两比较,小的放前面,大的放后面。
步骤
- 相邻的元素两两比较,大的放右边,小的放左边,找到最大值
- 第一次循环结束,最大值已经找到,在数组的最右边
- 下一次只要在剩余的元素中找最大值就可以了
- 如果有n个数据进行排序,总共需要比较n – 1次
- 每一次比较完毕,下一次的比较就会少一个数据参与
public class MyBubbleSortDemo{
public static void main(String[] args){
int[] arr = {
3, 5, 2, 1, 4}
;
bubbleSort(arr);
printArr(arr);
}
private static void bubbleSort(int[] arr){
// 循环排序
// 外层循环控制次数,比数组的长度少一次
for(int i = 0;
i arr.length - 1;
i++){
// 内存循环就是实际比较的次数
for(int j = 0;
j arr.length - 1 - i;
j++){
// -1为了让数组不越界,-i 是每轮结束后都会减少比较
if(arr[j] >
arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
private static void printArr(int[] arr){
// 循环遍历
for(int i = 0;
i arr.length;
i++){
System.out.print(arr[i] + " ");
}
System.out.println();
}
}
9.4.3. 递归
以编程角度来看,递归指的是方法定义中调用方法本身的现象
解决问题的思路:把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算
递归解决问题要有两个内容
- 递归出口:否则会出现内存溢出
- 递归规则:与原问题相似的规模较小的问题
案例
// 求1~100的和(递归实现)
public class MyFactorialDemo1{
public static void main(String[] args){
int sum = getSum(100);
System.out.println(sum);
}
private static int getSum(int i){
if(i == 1){
return 1;
}
else{
return i + getSum(i - 1);
// i + (i - 1)的和
}
}
}
// 需求:用递归求5的阶乘,并把结果在控制台输出
public class MyFactorialDemo2{
public static void main(String[] args){
int result = getJc(5);
System.out.println(result);
}
private static int getJc(int i){
// 出口
if(i == 1){
return 1;
}
else{
// 规则(递归下一次调用的,一定更接近出口)
return i * getJc(i - 1);
}
}
}
9.4.4. 快排
- 冒泡排序算法中,一次循环结束,就相当于确定了当前的最大值,也能确定最大值在数组中应存入的位置。
- 快速排序算法中,每一次递归时以第一个数为基准数,找到数组中所有比基准数小的。再找到所有比基准数大的。小的全部放左边,大的全部放右边,确定基准数的正确位置
public class MyQuiteSortDemo{ public static void main(String[] args) { int[] arr = { 6, 1, 2, 7, 9, 3, 4, 5, 10, 8} ; quiteSort(arr, 0, arr.length - 1); for (int i = 0; i arr.length; i++) { System.out.print(arr[i] + " "); } } private static void quiteSort(int[] arr, int left, int right) { if (right left) { return; } // 记录两个值 int left0 = left; int right0 = right; // 计算出基准数 int baseNumber = arr[left0]; while (left != right) { // 1.从右开始找比基准数小的 while (arr[right] > = baseNumber & & right > left) { right--; } // 2.从左开始找比基准数大的 while (arr[left] = baseNumber & & right > left) { left++; } // 3.交换两个值的位置 int temp = arr[left]; arr[left] = arr[right]; arr[right] = temp; } // 4. 基准数归位 int temp = arr[left]; arr[left] = arr[left0]; arr[left0] = temp; // 再次递归调用方法 quiteSort(arr, left0, left - 1); quiteSort(arr, left + 1, right0); } }
10、方法
方法就是一段具有独立功能 的代码块,不调用就不执行
10.1. 基本使用
- 方法必须先创建才可以使用,该过程称为方法的定义
- 方法创建后并不是直接运行的,需要手动使用后才执行,该过程称为方法调用
方法定义
public void 方法名(){
//方法体
}
方法调用:方法名();
注意
- 方法必须先定义后调用,否则程序将会报错
- 方法与方法之间是平级关系,不能嵌套定义
- 在方法没有被调用的时候,都在方法区中的字节码文件(.class)中存储
- 方法被调用的时候,需要进入到栈内存中运行
10.2. 带参方法
形参和实参 形参:全称形式参数,是指方法定义中的参数 实参:全称实际参数,是指方法调用中的参数
定义
public void 方法名(参数){
//方法体
}
单个参数:数据类型 变量名
多个参数:数据类型 变量名1 , 数据类型 变量名2 , .....
调用
方法名(变量名/常量值);
方法名(变量名1/常量值1 , 变量名2/常量值2 , ...);
方法调用时,参数的数量与类型必须与方法定义中的设置相匹配,否则程序将会报错
带参数方法练习
// 需求:设计一个方法(print)用于打印n到m之间的所有的奇数
public class a{
public static void main(String[] args){
print(10, 20);
}
public static void print(int n, int m){
for(int i = n;
i = m;
i++){
if(i % 2 != 0) {
System.out.println(i);
}
}
}
}
#10.3. 带返回值方法
定义
public 返回值数据类型 方法名(参数){
return 数据;
}
- 方法定义时,return后面的返回值与方法定义上的数据类型要匹配,否则就会报错
- 在执行代码时,return语句后面的语句都不会执行,属于无效代码
return;
可以用于结束方法,也就是方法从栈内存中弹出去,该过程称为方法的弹栈
调用:数据类型 变量名 = 方法名(参数);
方法通用格式
public 修饰符 返回值类型 方法名(参数){
方法体;
return 数据;
}
上面的案例中,方法都有static修饰符,现在只需要知道,在main中调用方法,对应的方法必须由static修饰即可
10.4. 方法重载
方法名相同,参数也完全相同,称为方法的重复定义,是一种冲突性的错误 在调用方法的时候,Java虚拟机会通过参数的不同来区分同名的方法
- 在同一个类中,定义了多个同名的方法,但每个方法具有不同的参数类型或参数个数,这些同名的方法,就构成了重载关系
- 好处:不用记忆过多繁琐的方法名字
- 注意:识别方法之间是否是重载关系,只看方法名和参数,和返回值无关
对于调用方法的人来说,方法的形参数据类型的重要程度要远远高于返回值,所以方法签名就由方法名+形参列表构成
方法重载练习
// 需求:使用方法重载思想,设计比较两个整数是否相同的方法,兼容全整数类型(byte,short,int,long)
public static void main(String[] args){
System.out.println(compare(20, 30));
}
public static boolean compare(byte a, byte b){
return a == b;
}
public static boolean compare(short a, short b){
return a == b;
}
public static boolean compare(int a, int b){
return a == b;
}
public static boolean compare(long a, long b){
return a == b;
}
方法的参数传递
- 当传入基本数据类型时,传入的是具体的数值,且方法中的变量和main中的变量并无联系
- 当传入引用类型时,传入的是具体的内存地址,这种情况可以在方法中改变引用类型变量的值
案例
// 需求:设计一个方法用于数组遍历,要求遍历的结果是在一行上的。例如:[11,22,33,44,55]
public static void main(String[] args) {
int[] arr = {
11, 22, 33, 44, 55}
;
printArray(arr);
}
public static void printArray(int[] arr) {
System.out.print("[");
for (int i = 0;
i arr.length;
i++) {
System.out.print(arr[i]);
if (i == arr.length - 1) System.out.print("]");
else {
System.out.print(", ");
}
}
}
// 需求:设计一个方法用于获取数组元素中的最大值
public static void main(String[] args){
int[] arr = {
11,33,44,88,22}
;
System.out.println("数组中的最大值为:" + max(arr));
}
public static int max(int[] arr){
int max = arr[0];
for(int i = 0;
i arr.length;
i++){
if(arr[i] >
max) max = arr[i];
}
return max;
}
// 需求:设计一个方法,该方法中能够同时获取最大值和最小值
public static void main(String[] args){
int[] arr = {
11,22,33,44,2,2393,55}
;
int[] res = get(arr);
System.out.println("最大值为:" + res[0]);
System.out.println("最小值为:" + res[1]);
}
public static int[] get(int[] arr){
int max = arr[0];
int min = arr[0];
for(int i = 0;
i arr.length;
i++){
if(arr[i] >
max) max = arr[i];
if(arr[i] min) min = arr[i];
}
int[] arrMaxAndMin = {
max, min}
;
return arrMaxAndMin;
}
注意:return语句只能同时返回一个值,需要返回多个值的话可以使用数组
11、进制
指进位制,是人们规定的一种进位方式
11.1. 常见进制
- 二进制:逢二进一,借一当二(只有0和1)
- 八进制:逢八进一,借一当八(0,1,2,3,4,5,6,7)
- 十进制:逢十进一,借一当十
- 十六进制:0~9,a~f(其中a~f表示10~15)
计算机数据在底层运算的时候,都是以二进制进行的,了解不同的进制,便于我们对数据的运算过程理解的更加深刻
进制表示
在Java中,数值默认都是十进制,不需要加任何修饰
- 二进制:数值前面以
0b
开头,b大小写都可 - 八进制:数值前面以
0
开头 - 十六进制:数值前面以
0x
开头,x大小写都可
注意:书写的时候,虽然加入了进制的标识,但打印在控制台展示的时候都是十进制数据
进制转换
- 任意进制到十进制公式:系数*基数的权次幂 相加
- 系数:每一【位】上的数
- 基数:几进制,就是几
- 权:从数值的右侧,以0开始,逐个+1增加
- 十进制到任意进制的转换公式:除基取余
- 使用源数据,不断地除以基数(几进制就是除几)得到余数
- 一直除到商为0为止
- 最后将余数倒序拼起来即可
- 快速进制转换法:8421码
- 8421码又称BCD码,是BCD代码中最常用的一种
- BCD:(Binary-Coded Decimal)二进制码十进制数
- 在这种编码方式中,每一位二进制值的1都是代表一个固定数值,把每一位的1代表的十进制数加起来得到的结果就是他所代表的十进制数
11.2. 原码反码补码
计算机中的数据,都是以二进制补码的形式在运算。补码是通过反码和原码推算出来的
原码:(可直观的看出数据大小)就是二进制定点表示法,最高位为符号位,0正1负,其余位表示数值的大小 一个字节等于8个比特位,也就是8个二进制位
反码:(将原码转换为补码)正数的反码与其原码相同,负数的反码是对其原码逐位取反,但符号位除外 补码:(数据以该状态进行运算)正数的补码与其原码相同,负数的补码是在其反码的末位加1
正数的原反补都是相同的 负数的【反码】,是根据【原码】取反(0变1,1变0)得到的 (符号位不变) 负数的【补码】,是根据【反码】的末尾+1得到的
11.3. 位运算
位运算指的是二进制位的运算,先将十进制数转换成二进制后再进行运算
在二进制位运算中,1表示true,0表示false
&
位与:遇false则false,遇0则0|
位或:遇true则true,遇1则1^
位异或:相同为false,不同为true (a = a ^ b ^ b)~
取反:全部取反,0变1,1变0(也包括符号位)
位移运算符
有符号左移运算,二进制位向左移动,左边符号位丢弃,右边补齐0
运算规律:向左移动几位,就是乘以2的几次幂
>
>
有符号右移运算:二进制位向右移动,使用符号位进行补位
运算规律:向右移动几位,就是除以2的几次幂
>
>
>
无符号右移运算符,无论符号位是0还是1,都补0
案例
// 需求:在不使用第三方变量的情况下,实现两数据交换
public static void main(String[] args){
int a = 10;
int b = 20;
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println(a);
System.out.println(b);
}
// 需求:实现数组元素的反转(交换数组中元素的值)
int[] arr = {
11, 22, 33, 44, 55, 66, 77}
;
for(int start = 0, end = arr.length - 1;
start end;
start++, end--){
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
for(int i = 0 ;
i arr.length;
i++){
System.out.println(arr[i]);
}
12、二维数组
二维数组也是一种容器,不同于一维数组,该容器存储的都是一维数组容器
定义格式
- 格式1:
数据类型[][] 变量名;
- 格式2:
数据类型 变量名[];
- 格式3:
数据类型[] 变量名[];
动态初始化:
数据类型[][] 变量名 = new 数据类型[m][n];
- m 表示这个二维数组可以存放多少个一维数组(行)
- n 表示每一个一维数组,可以存放多少个元素(列)
拓展:将一个提前创建好的一维数组存储到二维数组中
int[] arr = {
11, 22, 33}
;
int[][] arr2 = new int[1][3];
arr2[0] = arr;
System.out.println(arr2[0][2]);
静态初始化:
- 格式:
数据类型[][] 变量名 = new 数据类型[][]{ { 元素1, 元素2,...} , { 元素1, 元素2,...} ...} ; int[][] arr = new int[][]{ { 1, 2, 3} , { 4, 5, 6} } ;
- 简化格式:
数据类型[][] 变量名 = { { 元素1, 元素2,...} , { 元素1, 元素2,...} , ...} ; int[][] arr = { { 1, 2, 3} , { 4, 5, 6} } ;
二维数组遍历
- 已知一个二维数组
arr = { { 11, 22, 33} , { 33, 44, 55} } ;
- 遍历数组,取出所有元素并打印
int[][] arr = {
{
11, 22, 33}
, {
33, 44, 55}
}
;
for(int i = 0;
i arr.length;
i++){
for(int j = 0;
j arr[i].length;
j++){
System.out.println(arr[i][j]);
}
}
案例
二维数组求和
int sum = 0;
int[][] arr = {
{
22, 66, 44}
, {
77, 33, 88}
, {
25, 45, 65}
, {
11, 66, 99}
}
;
for(int i = 0;
i arr.length;
i++){
for(int j = 0;
j arr[i].length;
j++){
sum += arr[i][j];
}
}
System.out.println(sum);
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: Java基础入门教程-基础语法
本文地址: https://pptw.com/jishu/3367.html