数组+循环
使用场景
【批量】【同类型】数据的(存储)和(操作)
int num = 10;
int[] nums = null;
nums[0] = 0//空指针异常
1.数组类型==》决定元素类型
2.数组名称==》每个元素 数组名称[下标] nums[下标]
3.数组长度==》决定了最大元素下标 = 长度-1 数组长度一旦确定 不可改变 数组名.length属性
类型[] 数组名称 = new 类型[长度]; //int[] nums = new int[5];
类型[] 数组名称 = new 类型[]{值1,值2,值3...}有大括号放值 就不能在中括号中放长度
类型[] 数组名称 = {值1,值2,值3...}
//整数默认值0
//小数默认值0.0
//字符默认值空格 \u0000
//布尔默认值false
//String默认值null ==>所有引用数据类型的默认值 都是null
String str = null ;
//str.equals(null)
str==null
"null" null
str = "";
if(str!=null){
syso(str.equals("abcd")); //true/false
syso(str.charAt(0));
}
int[] nn = null;
syso(nn.length);//空指针
int num = 10;
int[] nums = new int[3];
//int nums[] = new int[3];
nums[0] = input.nextInt();
nums[1] = input.nextInt();
nums[2] = input.nextInt();
int[] nums = new int[]{35,22,78,42};
syso(nums[0]);
int[] nums = {56,13,78,45};
syso(nums[0]+" "+nums[1]+" "+nums[2]+" "+nums[3]);
syso("数组长度:"+nums.length);//属性
syso(Arrays.toString(nums)); //[56,13,78,45]
Math.PI
String s = "a";
String s = new String("a");
案例
打印10遍HelloWorld
为什么用循环有重复的操作
如何使用循环3.重复的代码(循环体)4.循环结束的条件 2.条件变化情况 1.条件的初始值
for循环
普通for循环
1.常用于循环次数固定的循环
2.次数固定 建议从0开始迭代 <次数 即可 ++
3.找循环四要素
//for(;;) ; {
//错误 多了;
//}
for( 1条件初始值 ; 2判断条件 ; 4条件变化){ 迭代
3循环体
}
1.初始值
for( ; 2.判断条件 ; ){
3.循环体
4.迭代情况
}
for(int i =0 ; i<次数 ; i++){
循环体
}
for(;;){
}
while(){
}
do{
}while();
for(int i = 0;i==0;){
syso("是否通过考试0.没通过1.通过了");
i = input.nextInt();
}
for(char isPath = 'n';isPath=='n';isPath = input.next().charAt(0)){
syso("努力学习 参加考试");
syso("是否通过 y/n");
//isPath = input.next().charAt(0);
}
char isPath = 'n';
while(isPath=='n'){
syso("努力学习 参加考试");
syso("是否通过 y/n");
isPath = input.next().charAt(0);
}
先判断 再执行 有可能一次都不执行
char isPath = 'y';
do{
syso("努力学习 参加考试");
syso("是否通过 y/n");
isPath = input.next().charAt(0);
}while(isPath=='n');
先执行 再判断 至少执行一次
int[] ages = new int[5];
for(int i = 0 ; i< ages.length ; i++){
ages[i] = input.nextInt(); //ages[4]
//syso("第"+(i+1)+"遍HelloWorld");
}
//直接输出数组名 展示的是其地址信息
syso(ages);I@asdf
for(int i =0;i<ages.length;i++){
syso(ages[i]);
}
sout(Arrays.toString(ages));//[xx,xx,xx,xx]
//String str = new String("adsf");
//String str = "asdf";
//int i = 12;
增强for循环
目前只适用于遍历展示数组(给数组赋值 和删除元素 不能使用 修改元素在某些情况下可用)
//如果是基本数据类型数组 修改不可用增强for循环
//如果是引用数据类型数组如果只是修改元素的属性 可用如果改变是地址 则不可用
for(类型 变量名 : 数组名){
}
先判断 再执行 有可能一次都不执行
String[] names = new String[3];
names[0] = "张三";
names[1] = "李四";
names[2] = "王五";
System.out.println(names);//地址
for(int i =0;i<names.length;i++) {
System.out.println(names[i]);
}
System.out.println("======================");
for(String n : names) { n = names[0]
//冒号左侧变量 来接受数组中每一个元素
System.out.println(n);
}
String str = Arrays.toString(scores);
System.out.println(str);
//元素的修改 【某些情况下】 不可使用增强for循环
int[] nums = {3,5,2,8,4,6}; //nums[0]
for(int i : nums){ // i = nums[0]; 都指向常量池中的3
// i = 50; nums[0]依然指向3
if(i%2!=0){
i++;
}
}
public class Dog{
String name;
int age;
String brand;
public String toString(){
return ...;
}
}
Dog[] ds = new Dog[3];
ds[0] = new Dog();
ds[0].name = "豆豆";
ds[0].age = 1;
ds[0].brand = "拉布拉多";
ds[1] = new Dog();
ds[1].name = "花花";
ds[1].age = 2;
ds[1].brand = "京巴";
ds[2] = new Dog();
ds[2].name = "饭饭";
ds[2].age = 1;
ds[2].brand = "二哈";
for(Dog d : ds){
syso(d);
}
int index = 0;
for(Dog d : ds){ d = ds[0]
if(d.name.equals("花花")){
//d = new Dog();
syso(d);
syso(ds[1]);
d.age = 100;
}
index++;
}
for(int i =0;i<ds.length;i++){
if(ds[i].name.equals("花花")){
ds[i] = new Dog();
}
}
练习
用户输入人数
循环询问保存这些人的姓名
循环展示所有人的姓名
展示出所有三字姓名的人
展示出所有姓张的人
统计姓李的有几人
循环询问保存用户输入人数各用户的年龄
展示每人的年龄
总年龄
平均年龄
统计大于平均年龄的人数
成年人百分比
while循环
1.变量初始值
while(2.判断条件){
3.循环体
4.变量变化情况
}
1.初始值
for( ; 2.判断条件 ; ){
3.循环体
4.迭代情况
}
先判断 再执行 有可能一次都不执行
案例
打印输出10遍HelloWorld
考试没通过则继续考试 直到通过为止 统计总共参加了几次考试
//1.判断条件的变量的初始化
int n = 0;
//2.判断条件
while(n<10) {
//3.循环体
System.out.println("第"+(n+1)+"遍HelloWorld");
//4.变量变化情况 迭代情况
n++;
}
for(int i =0;i<10;i++){
syso("HelloWorld");
}
int i = 0;//记录次数
//1.初始值
String str = "n";
//2.判断条件
while(str.equals("n")) {
i++; //每进入一次 次数+1
//3.循环体
System.out.println("努力学习 参加考试");
System.out.println("是否通过y/n");
//4.迭代情况
str = input.next();
}
System.out.println("总共参加了"+i+"次考试");
练习
用户输入要跑的圈数 循环展示 "用户在跑第x圈"分别使用for循环 和 while循环完成
用户循环跑圈 每跑一圈询问是否能继续 能则继续跑 不能则结束跑圈 统计总共跑了几圈
用户循环跑圈 每跑一圈询问用户是否喝水 y则"喝口水继续跑" n则"不渴继续跑"再询问用户是否能继续 n则停止跑圈 统计总共喝了几次水 跑了多少圈
do while循环
1.判断条件的变量不会影响循环是否继续
do{
2.循环体
3.改变判断条件的变量
}while(4.判断条件);
先执行 再判断 至少执行1次
逻辑关键字
while(){
if(){
break;//结束循环模块
syso();//报错 永远执行不到的语句
}
syso("sdf");
}
while(){
if(){
continue;//结束本次循环 执行下一次循环
syso();//报错 永远执行不到的语句
}
syso("sdf");
}
continue【结束本次循环 进入下一次循环】 1.后不能直接跟代码 2.只能使用在循环中
break【结束当前模块】1.不能直接使用在单独的if中 2.后不能直接跟代码
//return1.结束当前方法2.返回一个结果
String name = input.next();
syso(input.next());
if(input.next().equals("")){
}
syso(input.next().charAt(0))
syso(input.nextInt()+100):
1.男2.女
char gender = input.nextInt()==1?'男':'女';
//1.声明同类型变量接收方法返回值
//2.直接输出这个方法 就是输出返回值
//3.根据返回值的特性参与运算
Arrays类
Stringstatic toString(数组名称)格式化输出数组中的元素syso(Arrays.toString(数组名)); [元素,元素,元素,元素]
String str = Arrays.toString(数组名);
voidstaticsort(数组名)将数组进行升序排列Arrays.sort(数组名);(如果要降序 需要使用比较器)
同类型的数组staticcopyOf(老数组名,新数组长度)创建一个长度的新数组 将老数组元素复制到新数组 返回这个新数组
int[] nums = {5,2,7,9,1};
Arrays.sort(nums);
String str = Arrays.toString(nums);
syso(str); // [5,2,7,9,1]
for(int i =0;i<nums.length;i++){
if(nums[i]%2==1){
syso(nums[i]+"是奇数");
}else{
syso(nums[i]+"是偶数");
}
}
5 6 7 8 9
5 6 7
随机类
案例
随机产生一个10以内的整数
import java.util.Random;//导包
。。。。
Random r = new Random(); //创建对象
int num = r.nextInt(10);
syso(num); //[0 10)
//产生[10-20]随机数
int num = r.nextInt(11)+10;
//[45-78]
int num = r.nextInt(34)+45;
//[23-66] (最大值-最小值+1)+最小值
int num = r.nextInt(44)+23;
String str = "asdf";
char c = str.charAt(0);
int[] nums = {4,6,1,9,3,8};
int index = r.nextInt(nums.length); //产生数组范围内的下标
syso(nums[index]); //下标是随机获取的 因此对应的数字就是随机获取的
int num = 0;
while(num!=4&&num!=6&&num!=1&&num!=9&&num!=3&&num!=8){
num = r.nextInt(10);
}
syso(num);
String str = "abcdefg";
int index = r.nextInt(str.length()); //获取一个随机的下标
char c = str.charAt(index); //下标是随机的 因此对应的字符就是随机获取的
数组排序
案例
将数组元素 按升序重新排列 并展示
a b c d
int[] nums = {56,44,78,32,48,12,30,21,77,60};
//比较排序
for(int i =0;i<nums.length-1;i++){
//外层循环nums[i]表示要拿哪个元素去比较
for(int j=i+1;j<nums.length;j++){
//内层循环nums[j]表示后续所有要去比较的元素
if(nums[i]>nums[j]){
int l = nums[i];
nums[i] = nums[j];
nums[j] = l;
}
}
}
//冒泡排序
//外层循环n-1 内层循环n-i-1
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]) {
int l = nums[j];
nums[j] = nums[j+1];
nums[j+1] = l;
}
}
}
Arrays.sort(nums); //没有返回值的方法 直接调用即可
syso(Arrays.toString(nums));//[xx,xx,xx]
String s = Arrays.toString(nums);
//有返回值的方法
1.声明一个同类型的变量来接受这个方法(接收这个方法的返回值)
2.直接输出该方法 (输出带返回值的方法 就是输出这个值)
3.可以根据返回值的特性 参与运算
Arrays.toString(nums).equals("xxxx")
String str = input.next();
boolean b = str.equals("张三");
if(b){
}
if(str.equals("sdf")){
}
input.nextInt()==1?'男':'女'
int result = r.nextInt(100)*100
//r.nextInt(100)
数组复制
数组是一个引用数据类型 代表的是一个地址
案例
一个数组记录去年两名同学的身高 175 180
今年第一名同学长了10 第二名没有变 再次输出两个的身高
int[] h1 = new int[]{175,180};
int[] h2 = h1;//直接将h1的地址给到h2 会导致 两个数组共享地址
syso(h1); //[I@15db9742
syso(h2); //[I@15db9742
//h2[0] = 185;
//syso(h1[0]); //185 因为共享地址 导致h1元素也变化了
h2 = new int[h1.length]; //一定要创建一个新的数组地址
//只是将老数组的元素 复制给新数组元素
for(int i =0;i<h1.length;i++){
h2[i] = h1[i];
}
h2[0] = 185; //修改新数组元素
syso(h1[0]); //175 不会影响老数组元素
int[] h2 = Arrays.copyOf(h1,h1.length);
数组扩容
案例
创建一个数组 有2个空间 保存用户姓名
实现循环存储姓名 每存储一个 询问是否继续 直到不再继续为止
String[] names = new String[2];
while(true){
//1.扩容
//如果最后一个元素都不为null 说明都存满了 要扩容了
if(names[names.length-1]!=null){
//1.创建新数组
String[] newNames = new String[names.length+2];
//2.将老数组元素赋给新数组
for(int i =0;i<names.length;i++){
newNames[i] = names[i];
}
//3.将新数组地址 给到 老数组引用名
names = newNames;
//names = Arrays.copyOf(names,names.length+2);
syso("扩容成功 长度:"+names.length);
}
//2.找空房间 存值
for(int i =0;i<names.length;i++){
if(names[i]==null){ //找到第一个null房间 存值
syso("请输入姓名");
names[i] = input.next();
break; //每次只存一个姓名
}
}
//3.是否继续
syso("是否继续y/n");
char isGo = input.next().charAt(0);
if(isGo=='n'){
break;
}
}
//迭代展示所有非空元素
for(String n : names){
if(n!=null){
syso(n);
continue;
}
break;//如果找到 null 房间了 意味着后续都是null 不用再循环了
}
二分查找法
案例
int[] nums = {3,6,9,12,34,56,72,99,125,256,378};
查找用户输入的一个数字 在不在数组中
int num = input.nextInt();//用户要查找的值 //256
boolean bool = true;
for(int l : nums){
if(l == num){
syso("存在该值");
bool = false;
break;
}
}
if(bool){
syso("没找到");
}
67 78 89 456 789
//二分查找法
Arrays.sort(nums);//先升序排列
int leftIndex = 0;
int rightIndex = nums.length-1;
boolean bool = true;
while(leftIndex<=rightIndex){
//找当前的中间下标
int middleIndex = (leftIndex+rightIndex)/2;
if(num==nums[middleIndex]){
syso("找到了");
bool = false;
break;
}else if(num>nums[middleIndex]){
//要查找的值在右侧 应该移动左挡板向右
leftIndex = middleIndex+1;
}else{
//在左侧 要向左移动右挡板
rightIndex = middleIndex-1;
}
}
if(bool){
syso("没找到要查找的值");
}
案例
三个数组 一个保存用户姓名 一个保存年龄 一个保存性别
1.注册可以一直注册 每次注册一人信息要求姓名不能重复
2.姓名查询如果存在 展示所有信息
3.修改信息输入姓名 修改该用户的其他信息
4.性别查找输入性别 展示所有该性别的用户信息
5.删除信息输入姓名 如果存在 则将该用户的所有信息删除
6.年龄排序选择升序或降序 展示每个人的信息
7.退出
//输入非菜单数字 则提示输入有误 重新输入
//输入非数字 提示输入格式有误 重新输入 input.hasNextInt()
二维数组
数组的元素 又是一个数组
1.最终保存的数据类型 大数组类型 小数组类型 必须一致
2.长度的设定
1.每个元素指向的小数组长度一定
在创建大数组时 会自动创建小数组对象
2.每个元素指向的小数组长度不一定
小数组需要单独创建对象
二维数组声明
//已知小数组长度 并且小数组长度一致
int[][] ages = new int[3][5];
//一边创建3个长度的大数组ages
//一边创建5个长度的小数组 ages[0] ages[1] ages[2]
//ages[0] = new int[5];
//ages[1] = new int[5];
//ages[2] = new int[5];
//如果没有确认小数组共同的长度 则需要单独创建小数组
int[][] ages = int[3][];
//ages[0] = new int[6];
//ages[1] = new int[4];
//ages[2] = new int[5];
for(int i =0;i<ages.length;i++){
syso("第"+(i+1)+"个小数组长度");
int num = input.nextInt();
ages[i] = new int[num]; //需要自己独立创建小数组对象
for(int j = 0;j<ages[i].length;j++){
ages[i][j] = input.nextInt();
}
}
//展示所有元素
for(int[] n:ages){
//syso(Arrays.toString(n));
for(int m : n){
syso(m+"\t");
}
syso();
}
for(int i =0;i<ages.length;i++){
for(int j = 0;j<ages[i].length;j++){
syso(ages[i][j]+"\t");
}
syso();
}
评论