五 Java详细基础(控制结构 循环控制语句 idea使用 数组)

控制结构

循环结构:重复执行同一段代码
循环四要素:
1、初始化条件语句:
定义一个变量 通常用于循环条件的控制
2、循环条件:
控制循环是否结束的
结果必须是boolean类型
true:循环继续
false:循环结束

3、循环体:重复执行的代码
4、改变循环条件的语句:

每执行完一次循环体之后 要改变循环条件的结果

案例:
打印100次hello world

循环体:System.out.println(“hello world”);
循环条件:打印次数<=100 num<=100
初始化条件语句:定义变流量表示打印次数 int num = 1;
改变循环条件的语句:num=num+1;或者num++;

分类:while do.while for

while:
格式:

初始化条件语句;
while(循环条件){
循环体;
改变循环条件的语句;
}

执行流程:
1、初始化条件语句
2、循环条件
true:循环体;
改变循环条件的语句;
重复步骤2;
false:循环结束

在这里插入图片描述
案例:打印1.。。。99
在这里插入图片描述
在这里插入图片描述
案例:1+2+3…+10
在这里插入图片描述
在这里插入图片描述

do.while:
格式:

初始化条件语句;
do{
循环体;
改变循环条件的语句;
}while(循环条件);

分号必须加

执行流程:
1、初始化条件语句
2、循环体;
3、改变循环条件的语句;
4、循环条件
true:重复步骤2
false:结束循环

while和do.while的区别:
当第一次执行循环条件不成立时:
do while一定会先执行一次循环体;
while则一次循环体都不会执行;
do.while无论循环条件是否成立,都会先执行一次循环体;
while循环如果循环条件不成立,则循环体一次都不会执行;

在这里插入图片描述
因为循环条件再后面,前面没法判断,判断的语句在后面
在这里插入图片描述

案例:

1、循环打印88次hello world
在这里插入图片描述

2、打印1 2 3 …99
在这里插入图片描述

3、求1+2+3…+10

在这里插入图片描述
在这里插入图片描述
这是个死循环(循环不会结束,当循环条件一直为true时),因为num一直小于10
要改成下面的
在这里插入图片描述
常见的死循环的形式:
while(true){}
for(; ; ){}

使用场景:当用户名不符合条件时,不停的重新输入

注意:如果程序在编译期间可以确定是死循环,则死循环后边的代码编译报错;

for循环

和while循环执行流程完全一致,区别在与格式上略有不同
格式:
for(初始化条件语句;循环条件语句;改变循环条件的语句){
循环体;
}

执行流程:
1、初始化条件语句
2、循环条件
true:循环体;
改变循环条件的语句;
重复步骤2;
false:循环结束
在这里插入图片描述
案例:
1、循环打印50次hello world
在这里插入图片描述

2、打印1 2 3 …99
在这里插入图片描述

3、求1+2+3…+10
两种
下面这种不行,找不到sum
因为sum变量的作用域只在for循环生效,出了for循环没法用(i也是)
在这里插入图片描述
在这里插入图片描述
变量作用域:变量生效的范围
通常情况下:从变量定义开始到该变量所属的{}结束
当变量所属的{}执行完成,变量的内存空间随之释放;可以提高内存的利用率;
在同一个作用域中变量不能重名;

循环嵌套:循环嵌套if判断语句
将if看做循环体

案例:输出100以内所有能被5整除的整数
5 10 15 20 25 30 …
法1
在这里插入图片描述
法2
在这里插入图片描述
在这里插入图片描述

循环嵌套循环
先执行内层循环,再进行外层循环
将内层循环看做外层循环的循环体

在这里插入图片描述
案例:打印99乘法表
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
给空格对不齐在这里插入图片描述
在这里插入图片描述
用/t做缩进
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

循环控制语句

break:打断
break;–break语句
应用场景:
1、switch case
结束switch case
2、循环
结束循环

在这里插入图片描述
i=4的时候不输出了,被break打断了
在这里插入图片描述

continue:继续
continue;–continue语句
跳过当次循环 继续下一次循环
应用场景:循环中
在这里插入图片描述
i=4的时候,跳过了

在这里插入图片描述

return:返回
return;结束方法
在这里插入图片描述
return结束方法,main方法也结束了
在这里插入图片描述

循环嵌套中 break和continue的用法:
当在循环嵌套中使用break和continue语句时,默认情况下只对它所属的离它最近(就近原则)的循环生效;

idea

调整主题:file->settings->apperance->theme
调整字体大小:file->settings->editor->font

使用步骤:
1、Project–项目 工程
开发的项目名称
需要选择自己安装的JDK
指定项目名称
项目的位置:最好不要放在c盘
项目是硬盘上的一个目录,再该目录下生成了一些文件夹和文件用于idea对当前项目进行管理(.idea javase.iml)
2、Module—模块
例如:淘宝下有购物车 用户 商品模块
在项目上右键选择new module
输入模块名称即可
创建模块其实是在project的目录下又创建了一个子目录用于进一步的区分和管理
在这里插入图片描述

3、src目录 源码所在的目录
4、package–包
Java文件进行再次分类管理
在src右键new package
cn.tedu.array
创建包是在src下又创建了cn目录 在cn目录下创建了tedu 在tedu目录下又创建array目录
5、在包里创建java类
指定类名即可
在这里插入图片描述
在这里插入图片描述

快捷键:
ctrl+/ 添加、取消行注释
ctrl+shift+/ 添加、取消块注释
ctrl+d 快速复制一行
ctrl+x 快速删除一行
ALT+Enter 快速提示

数组

引出:定义变量表示全班同学的年龄
问题:人数多的情况下,需要定义大量变量,操作麻烦
当计算例如平均年龄时,表达式也非常长,不方便使用

概念:可以存储多个同一数据类型的 长度固定 内容可变的容器

定义数组的格式:
格式一:数据类型[] 数组名 = {元素1,元素2,…};
例如:int[] ages = {18,16,88};

特点:当创建数组时确定数组中元素的值时,可以使用这种格式;
数组长度等于元素的个数

格式二:数据类型[] 数组名 = new 数据类型[长度];
例如:
int[] ages = new int[5];
特点:当创建数组时不知道元素的内容时,使用当前方式创建
指定了数组的长度

格式三:数据类型[] 数组名 = new 数据类型[]{元素1,元素2,…};
例如:int[] ages = new int[]{18,16};

特点:格式一基于格式三来进行简化的
数组长度等于元素的个数

注意:1、数组定义 格式二和格式三支持先声明后赋值,但是简化的格式一不支持;
2、[]可以在数据类型的后边 也可以在变量名的后边(建议放数据类型后边)
在这里插入图片描述

//格式二
int[] ages;
ages = new int[5];
//格式三
int[] ages;
ages = new int[]{
    
    16,18};

数组基本操作:
索引(下标):元素的编号 范围:0~数组的长度-1

1、获取数组中元素的值
格式:数组名[下标]
例如:ages[0]–获取ages数组的第一个元素

int[] ages = {
    
    17,18,19};
System.out.println(ages[0]);

在这里插入图片描述

注意:
如果下标超出范围,编译没问题,运行会抛出异常:
ArrayIndexOutOfBoundsException–数组下标越界异常

2、设置数组元素的值/修改元素的数据值也可以
创建数组时没有直接给定元素值,之后需要给元素依次赋值
数组名[下标] = 值;
例如:ages[0] = 10;

        int[] ages = new int[5];
        ages[0] = 16;
        System.out.println(ages[0]);

在这里插入图片描述

3、数组的长度
格式:数组名.length
例如:
ages.length

4、遍历数组
法一:通过for while循环

        int[] ages = {
    
    16,18,20};
        for (int i = 0; i <ages.length; i++) {
    
    
            System.out.println(ages[i]);
        }

在这里插入图片描述
法二:foreach-增强for循环 JDK1.5版本

应用场景:数组 集合

格式:
for(数据类型 变量名(声明了一个临时变量):数组名){
可以通过变量来使用当前数组元素的值
}

执行流程:
将数组中第一个元素赋值给变量,在循环体中可以通过变量获取到数组的元素值;
将数组中第二个元素赋值给变量,在循环体中可以通过变量获取到数组的元素值
将数组中第三个元素赋值给变量,在循环体中可以通过变量获取到数组的元素值

将最后一个元素赋值给变量
        //增强for循环 ages数组里的数据依次给age,然后再输出
        //int类型要与ages数据一致
        for (int age:ages) {
    
    
            System.out.println(age);
        }

法三:Arrays–jdk 提供的数组的一个工具类
Arrays.toString(数组名);
如果只是为了输出打印或者要将数组所有元素都转成一个字符串
例如:

//要导包
System.out.println(Arrays.toString(ages));

在这里插入图片描述

        //遍历数组并且修改元素的值
        for (int i = 0; i <ages.length ; i++) {
    
    
            ages[i] *=2;
        }
        System.out.println(Arrays.toString(ages));

在这里插入图片描述

for和foreach的区别:如果只是获取数组元素的值,两种都可以;
如果在遍历的过程中,想修改数组中元素的值:
for可以通过下标直接修改元素的值
foreach因为没有下标,当通过变量来修改时 无法影响数组的元素值

问题1:foreach循环不会影响值
for (int age:ages) {
age *= 2;
}

问题2:
直接输出数组名时 得到的值[I@28d93b30

问题3:当创建数组没有指定元素内容时,数组元素的值为什么int 是0,boolean的为false?
在这里插入图片描述
在这里插入图片描述
数组内存
内存:内存中的数据 一旦计算机重启或者意外宕机,内存中的数据全部丢失。内存处理效率高
硬盘:只要硬盘硬件不损坏,则无论计算机是否重启,数据都不会丢失;处理效率低。
Java程序运行是要占用内存空间;

操作系统在Java运行时都会单独给Java进程开辟一块内存空间;

Java内存:
1、栈内存
2、堆内存
3、方法区
4、本地方法栈
5、寄存器

栈内存:局部变量
每个方法执行时都在栈中有一块单独的空间
当方法执行完成 这块空间就会被释放

堆内存:new出来的对象
对象什么时候释放取决于垃圾回收器
垃圾回收器扫描时会判断当前对象是否还被使用,如果在使用则不会释放,如果没有被使用 则会释放空间;
垃圾回收器不由程序员来控制
空间必须有值,堆会给定默认值
默认值取决于数据类型:

byte short int:0
long:0L
float/double:0.0
char:\u0000 空字符
boolean:false
引用数据类型:null

在这里插入图片描述
上图:输出ages【0】时,先去栈内存中找,然后得到地址值,再根据地址值去堆内存中找

在这里插入图片描述
下图:用实际值将默认值替换掉
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
案例:下图是同一个地址值在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
数组的高级应用:

1、求数组所有元素的和
在遍历数组的过程中累加求和即可
普通for:

public class ArrayDemo {
    
    
    public static void main(String[] args) {
    
    
        int[] nums={
    
    3,16,17};
        //遍历
        int sum = 0;
        for (int i = 0; i < nums.length ; i++) {
    
    
            sum +=nums[i];
        }
        System.out.println("和为"+sum);
    }
}

增强for循环(对于没有修改数组里面的值来说合适)

        int sum = 0;
        for (int num:nums) {
    
    
            sum +=num;
        }
        System.out.println("和为"+sum);
    }

2、获取数组中元素的最大值/最小值

        //求数组的最大值
        int[] nums={
    
    3,16,17,30,26,-11};
        int max = nums[0];
        for (int i = 1; i <nums.length ; i++) {
    
    
            //max与数组每个元素都比较
            if (max<nums[i]){
    
    
                max = nums[i];
            }
        }
        System.out.println(max);
    }
}

3、反转数组
a、不改变数组 倒着输出

        int[] nums ={
    
    3,16,17,30,26,1};
        //i=0   nums.length-1
        //i=1   nums.length-1-1
        //i=2   nums.length-1-2
        //i     nums.length-1-i
        for (int i = 0; i <nums.length ; i++) {
    
    
            System.out.println(nums[nums.length-1-i]);
        }

在这里插入图片描述
或者从后面往前输出

        for (int i = nums.length-1; i >=0 ; i--) {
    
    
            System.out.println(nums[i]);
        }

b、直接将数组本身反转
在同一个数组中 通过下标控制进行首尾两个元素的交换

        //数组反转
        //nums[0]  nums[nums.length-1]交换
        //nums[1]  nums[nums.length-1-1]
        //nums[i]  nums[nums.length-1-i]
        // 就像两个变量交换 用临时变量可以
        // 再循环交换  i要小于数组长的一半
        int[] nums ={
    
    3,16,17,30,26,1};
        for (int i = 0; i <nums.length/2; i++) {
    
    
            int temp = nums[i];
            nums[i] = nums[nums.length-1-i];
            nums[nums.length-1-i] = temp;
        }
        System.out.println(Arrays.toString(nums));
        }
    }

在这里插入图片描述
c、创建一个新的数组 将原数组的数据倒着赋值给新数组

        int[] nums ={
    
    3,16,17,30,26,1};
        //先创建一个新的数组,新数组的长度由旧数组决定
        int[] newNums = new int[nums.length];
        for (int i = 0; i <newNums.length ; i++) {
    
    
            newNums[i] = nums[nums.length-1-i];
        }
        nums = newNums;//将新newnums的地址给nums 变成想要的数组
        System.out.println(Arrays.toString(newNums));
        System.out.println(Arrays.toString(nums));

在这里插入图片描述
4、查找数组元素
方式一:遍历数组 一一比较(缺点查找效率低)

        int [] nums = {
    
    1,22,76,45,4,45};
        int snum = 45;
        for (int i = 0; i <nums.length ; i++) {
    
    
            if (snum == nums[i]){
    
    
                System.out.println("该元素为第"+(i+1)+"个元素");
//                break;
            }
        }

在这里插入图片描述

方式二:二分查找(折半查找)
前提条件:数组必须有序

在这里插入图片描述

        int [] nums = {
    
    4,5,7,8,16,20,45};
        int snum = 45;//要查的数
        int min = 0;//最小下标
        int max = nums.length-1;//最大下标
        while (min<=max){
    
    
            int mid = (min+max)/2;//中间下标
            if (snum==nums[mid]){
    
    
                System.out.println(mid);
                break;
            }else if (snum>nums[mid]){
    
    
                min=mid+1;
            }else if (snum<nums[mid]){
    
    
                max = mid-1;
            }
        }

在这里插入图片描述
5、数组排序–排序算法
a. 冒泡排序
在这里插入图片描述

        //冒泡排序
        int [] nums = {
    
    9,2,8,1,3};
        for (int i = 1; i <=nums.length ; i++) {
    
     //i表示轮数 1-数组的长度-1轮
            //第i轮比较
            for (int j = 1; j <=nums.length-i ; j++) {
    
    //j表示比较次数 1-数组长度-i次
                //第i轮的第j次比较
                if (nums[j-1]>nums[j]){
    
     //降序把大于号改了即可
                    //交换位置;
                    int temp = nums[j-1];
                    nums[j-1] = nums[j];
                    nums[j] = temp;
                }
            }
        }
        System.out.println(Arrays.toString(nums));

在这里插入图片描述
b.选择排序
在这里插入图片描述

//        选择升序排序
        int [] nums = {
    
    9,2,8,1,3};
        for (int i = 1; i <=nums.length-1 ; i++) {
    
     //i为轮数
            //第i轮的比较
            for (int j = i; j <=nums.length-1; j++) {
    
     //j为次数
                if (nums[i-1]>nums[j]){
    
    
                    int temp = nums[i-1];
                    nums[i-1] = nums[j];
                    nums[j] = temp;
                }
            }
        }
        System.out.println(Arrays.toString(nums));

在这里插入图片描述
可以通过每轮比较记录最小值的下标,来实现每轮至多交换一次的效果;可以提高排序的效率

        //选择排序的优化
        int [] nums = {
    
    9,2,8,1,3};
        for (int i = 1; i <nums.length ; i++) {
    
    
            int index = i-1;//表示最小值的下标 初始为当前元素
            for (int j = i; j <=nums.length-1 ; j++) {
    
    
                if (nums[index]>nums[j]){
    
    //判断index指向的元素是否为最小值
                    index = j;//认为j为最小值,给index

                }
            }
            if (index!=i-1){
    
     //判断是否需要交换
                //交换
                int temp = nums[index];
                nums[index] = nums[i-1];
                nums[i-1] = temp;
            }
        }
        System.out.println(Arrays.toString(nums));

c.插入排序 快速排序 归并排序(面试前选择一个准备一下)

**但是开发时给了工具类
Arrays.sort(数组名);注意:默认只能升序排序

        int [] nums = {
    
    9,2,8,1,3};
        Arrays.sort(nums);
        System.out.println(Arrays.toString(nums));

在这里插入图片描述
d、数组的"扩容"、复制
int[] ages = new int[10];
数组一旦创建 长度固定不可变

a1、自己实现扩容
创建新的数组 长度为扩容之后的长度
将原来数组的数据拷贝到新数组中
将新数组的地址赋值给原数组

        int [] ages = {
    
    18,16,29,10,22};//原数组
        //假设要在以上数组中增加两个元素
        //数组一旦创建长度不变
        //创建新的数组
        int[] newAges = new int[ages.length+2];
        //将原数组的数据拷贝到新数组中
        for (int i = 0; i <=ages.length-1 ; i++) {
    
    
            newAges[i] = ages[i];
        }
        newAges[5] = 30;
        newAges[6] = 31;
        System.out.println(Arrays.toString(newAges));
        //将新数组赋值给原数组变量
        ages = newAges;//把newAges的值赋值给ages
        System.out.println(Arrays.toString(ages));

在这里插入图片描述
扩容实际是新开辟地址
在这里插入图片描述

a2、System.arraycopy() (直接帮我们实现扩容)
在这里插入图片描述
src:原数组名
srcPos:原数组起始元素的下标
dest:新数组名
destPos:新数组起始元素的下标
length:元素的个数

        int [] ages = {
    
    18,16,29,10,22};
        int[] newAges = new int[ages.length+2];
        System.arraycopy(ages,0,newAges,0,ages.length);
        System.out.println(Arrays.toString(newAges));

在这里插入图片描述

a3、Arrays.copyOf()
在这里插入图片描述
实际底层就是arraycopy方法
在这里插入图片描述

        int [] ages = {
    
    18,16,29,10,22};
        //Arrays已经帮你拿到了数组,要想拿这个数组就要赋值给这个数组类型的变量
//        int[] newAges = Arrays.copyOf(ages,7);//并不会改变原有的ages数组
//        ages = Arrays.copyOf(ages,7);
        //长度比原来小是缩容 大是扩容
        ages = Arrays.copyOf(ages,3);//新数组地址值赋值给原数组
        System.out.println(Arrays.toString(ages));

在这里插入图片描述

注意:1、基于System.arraycopy()实现的
2、copyOf支持扩容和缩容

二维数组
概念:数组的每个元素又是一个一维数组的
定义格式:
格式一:数据类型[ ] [ ] 数组名 = { {元素11,元素12,…},{元素21,元素22,…},…};

例如:
int[ ][ ] agess = { {16,18},{12,15,14}};

理解:
1、二维数组包含了两个一维数组
2、第一个一维数组包含了两个元素;第二个一维数组包含了三个元素;

特点:
1、在定义数组时确定每个元素具体的值
2、二维数组的长度:一维数组的个数

格式二:
数据类型[ ][ ] 数组名 = new 数据类型[一维数组的个数] [ 每个一维数组中元素的个数 ];
例如:int[][] agess1 = new int[3][5];

理解:
agess1二维数组包含了3个一维数组
每个一维数组中包含了5个元素

特点:
每个一维数组中元素的个数都是一致

格式三:数据类型 [ ][ ] 数组名 = new 数据类型[一维数组的个数][ ];

例如:int[ ][ ] agess2 = new int[3][ ];

特点:指定当前二维数组包含了几个一维数组 但是每个一维数组元素个数没有指定

基本使用
1、获取下标对应的一维数组对象
数组名[下标]
int[ ][ ] agess = { {16,18},{12,15,14}};
agess[0]–获取二维数组的第一个一维数组

2、获取下标为i的一维数组的下标为j的元素值
数组名[i][j]

3、二维数组的长度–一维数组的个数
数组名.length

4、取指定一维数组中元素的个数
数组名[下标].length

        int[][] ages = {
    
    {
    
    16,17},{
    
    15,20,22}};
        System.out.println(ages);
        System.out.println(ages[0]);
        System.out.println(ages[1]);
        //获取第一个一维数组的第一个元素
        System.out.println(ages[0][0]);
        System.out.println(ages[1][0]);
        //获取一维数组的个数
        System.out.println(ages.length);
        //获取第一个一维数组中元素的个数
        System.out.println(ages[0].length);
        System.out.println(ages[1].length);//第二个

在这里插入图片描述

5、遍历二维数组
普通for循环

二维数组的内存结构:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43872169/article/details/113878138