一、数组
1.1 概述
- 用来存放一组数据的数据结构
- 数组创建(3种语法):
1. int[] a = new int[5];
新建5个长度的 int[] 数组
5个位置,存默认值 0
把数组的地址,存到变量a
2. int[] a = {5,2,6,7,1,2,3};
3. 为存在的数组变量,重新赋一个新的数组,并且,直接初始化数组数据
a = new int[]{4,6,1};
- 数组的长度属性
- a.length
- 数组一旦创建,长度不可变
- 数组长度,可以是0
- 最大下标是 a.length - 1
- 数组的遍历
从头到尾,依次访问每一个位置
for(int i=0; i<a.length; i++) {
a[i]
}
1.2 练习:数组
项目:数组
类:Test1
package day0407;
import java.util.Arrays;
public class Test1 {
public static void main(String[] args) {
System.out.println("\n\n--------------");
f1();
System.out.println("\n\n--------------");
f2();
System.out.println("\n\n--------------");
f3();
}
private static void f1() {
//新建 int[],长度5
//再把它的内存地址,存到变量a
int[] a = new int[5];
System.out.println(a[2]);
a[2] = 6;
//打印数组的全部数据
//Arrays.toString(a)
//把数组所有数据,连接成字符串
// "[0, 0, 6, 0, 0]"
System.out.println(Arrays.toString(a));
}
private static void f2() {
char[] a = {'a', 'b', 'c'};
System.out.println(Arrays.toString(a));
a = new char[]{'h','e','l','l','o'};
System.out.println(Arrays.toString(a));
}
private static void f3() {
int[] a = {6, 7, 8, 9, 10};
// 交换 1 和 3 位置的值
int t = a[1];
a[1] = a[3];
a[3] = t;
System.out.println(Arrays.toString(a));
}
}
1.3 练习:随机打乱数组内数据排序
package day0407;
import java.util.Arrays;
import java.util.Random;
public class Test2 {
public static void main(String[] args) {
//调用f()方法,从方法获取一个int[]数组
int[] a = f();
//遍历打印数组数据
for(int i=0; i<a.length; i++) {
System.out.println(a[i]);
}
System.out.println("\n\n----------------");
//把a数组,传递到 shuffle() 方法打乱顺序
shuffle(a);
System.out.println(Arrays.toString(a));
}
private static void shuffle(int[] a) {
/*
* j
* [4, 2, 3, 1, 5]
* i
*
* *) i循环遍历数组
* *) 随机定位下标j与i交换
*/
for (int i = 0; i < a.length; i++) {
//随机下标j,范围:[0, a.length)
int j = new Random().nextInt(a.length);
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
private static int[] f() {
//新建int[]数组,长度5
//再把它的内存地址存到变量 a
int[] a = new int[5];
//遍历访问5个位置,填入1,2,3,4,5
for(int i=0; i<a.length; i++) {
a[i] = i+1;
}
//返回数组,把数组返回到调用位置
//本质是把数组地址返回去
return a;
}
}
1.4 练习:九九乘法表
项目:九九乘法表
类:Test1
把99乘法表,保存到 d:\99乘法表.txt
package day0408;
import java.io.FileWriter;
import java.io.IOException;
public class Test1 {
public static void main(String[] args) throws IOException {
//向文件输出文本数据的工具
//ctrl+1,选择 add throws ...
FileWriter out =
new FileWriter("d:\\99乘法表.txt");
//i循环1到9行
for(int i=1; i<=9; i++) {
//j循环 1到i 列
for(int j=1; j<=i; j++) {
if(j==3 && (i==3||i==4)) {
System.out.print(" ");
out.write(" ");
}
System.out.print(
j+"*"+i+"="+(j*i)+" ");
out.write(j+"*"+i+"="+(j*i)+" ");
}
System.out.println();
out.write("\r\n");
}
out.close();//关闭文件
}
}
1.5 练习:货物入库
names
["A", "B", "C"]
price
[2, 8, 3]
numbers
[200, 300, 180]
项目:货物入库查询
类:Test1
package day0503;
import java.util.Scanner;
public class Test1 {
//成员变量
static String[] names = {"iPhoneXS"," 华 为 Mate 20 pro"," 小 米 X","vivo
NEX","oppo Find"};
static double[] price = {8999,5399,2399,4399,3999};
static int[] numbers = {50,20,80,120,90};
public static void main(String[] args) {
/*
* ----------------------
* 1. 商品列表
* 2. 商品录入
* 3. 商品查询
* 4. 统计信息
* 5. 退出
* ----------------------
* 选择:> 1
* ....
*/
//死循环显示菜单
outer:
while(true) {
//显示菜单,并获得选择的值
int c = menu();
//判断c的值
switch(c) {
case 1: f1(); break;
case 2: f2(); break;
case 3: f3(); break;
case 4: f4(); break;
case 5: break outer;
}
}
}
private static int menu() {
System.out.println("----------------------");
System.out.println("1. 商品列表");
System.out.println("2. 商品录入");
System.out.println("3. 商品查询");
System.out.println("4. 统计信息");
System.out.println("5. 退出");
System.out.println("----------------------");
System.out.print("选择:> ");
return new Scanner(System.in).nextInt();
}
private static void f1() {
/*
names
["A", "B", "C"]
price
[2, 8, 3]
numbers
[200, 300, 180]
0 1 2
1. 名称:xx,价格:xx,数量:xx
*/
for(int i=0;i<names.length;i++) {
String n = names[i];
double p = price[i];
int b = numbers[i];
System.out.println(
(i+1)+". 名称:"+n+",价格:"+p+",数量:"+b);
}
}
private static void f2() {
/*
names
["A", "B", "C"]
price
[2, 8, 3]
numbers
[200, 300, 180]
0 1 2
*/
//遍历数组
for (int i = 0; i < names.length; i++) {
System.out.println("录入第"+(i+1)+"件商品:");
System.out.print("名称:");
String n = new Scanner(System.in).nextLine();
System.out.print("价格:");
double p = new Scanner(System.in).nextDouble();
System.out.print("数量:");
int b = new Scanner(System.in).nextInt();
names[i] = n;
price[i] = p;
numbers[i] = b;
}
//重新现实商品列表
f1();
}
private static void f3() {
/*
names
["A", "B", "C"]
price
[2, 8, 3]
numbers
[200, 300, 180]
0 1 2
字符串,比较是否相等,要用equals()方法
a = "aaa"
b = "aaa"
a.equals(b)
*/
System.out.print("输入查询的商品名:");
String n = new Scanner(System.in).nextLine();
//遍历数组
for (int i = 0; i < names.length; i++) {
// n 和 names[i] 相等
if(n.equals(names[i])) {
String name = names[i];
double p = price[i];
int b = numbers[i];
System.out.println(
(i+1)+". 名称:"+name+",价格:"+p+",数量:"+b);
return;
}
}
//循环结束,所有商品都比较完,没有找到
System.out.println("找不到商品");
}
private static void f4() {
/*
names
["A", "B", "C"]
price
[2, 8, 3]
numbers
[200, 300, 180]
0 1 2
*/
//商品总价,单价均价,最高单价,最高总价
double spzj = 0;//商品总价
double djzj = 0;//单价总价
double zgdj = 0;//最高单价
double zgzj = 0;//最高总价
//遍历数组
for (int i = 0; i < names.length; i++) {
spzj += price[i] * numbers[i];
djzj += price[i];
//数组中,找到更大的值
if(price[i] > zgdj) {
zgdj = price[i];//更大值存到这个变量
}
if(price[i]*numbers[i] > zgzj) {
zgzj = price[i]*numbers[i];
}
}
System.out.println("商品总价:"+spzj);
System.out.println("单价均价:"+(djzj/names.length));
System.out.println("最高单价:"+zgdj);
System.out.println("最高总价:"+zgzj);
}
}
1.6 练习:冒泡排序
项目:冒泡排序
类:Test1
package day0504;
import java.util.Arrays;
import java.util.Random;
public class Test1 {
public static void main(String[] args) {
//调用方法,从方法获取一个乱序数组
int[] a = suiJi();
System.out.println(Arrays.toString(a));
System.out.println("----------------");
//调用方法,对数组a进行排序
sort(a);
System.out.println("----------------");
System.out.println(Arrays.toString(a));
}
private static int[] suiJi() {
//产生一个随机的长度值n
// [5, 11)
// 5+ [0, 6)
int n = 5+ new Random().nextInt(6);
//新建长度是n的int[]数组
int[] a = new int[n];
//遍历填入100内的随机整数
for (int i = 0; i < a.length; i++) {
a[i] = new Random().nextInt(100);
}
return a;
}
private static void sort(int[] a) {
/* a.length-1
* j
* [6, 9, 82, 60, 63, 83, 89, 93]
* i
*/
//i循环遍历数组
for(int i=0;i<a.length;i++) {
boolean flag = false; //没有交换
//内层j循环,把较小值向前推,
//把最小值,推到i位置
//j循环,从末尾到>i,递减
for(int j=a.length-1; j>i; j--) {
//j和j-1位置,较小值向前交换
if(a[j] < a[j-1]) {
int t = a[j];
a[j] = a[j-1];
a[j-1] = t;
flag = true;//表示交换了数据
}
}//j循环结束
//如果flag是false,j执行过程中没有交换
if(! flag) {
break;
}
System.out.println(Arrays.toString(a));
}
}
}
1.7 练习:二分查找
在有序数组中,查找目标值的位置
12
[1,1,2,5,5,7,8,9,12,22,23,66]
项目:二分法查找
类:Test1
package day0505;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
public class Test1 {
public static void main(String[] args) {
//从方法,获取一个乱序数组
int[] a = suiJi();
//对a数组排序
Arrays.sort(a);//优化的快速排序
System.out.println(Arrays.toString(a));
while(true) {
System.out.print("查找的目标值:");
int t = new Scanner(System.in).nextInt();
//二分法查找,
//从a数组中,查找t的位置
int index = binarySearch(a, t);
System.out.println(index);
}
}
private static int[] suiJi() {
//随机产生5+ [0,6)范围整数n
int n = 5+ new Random().nextInt(6);
//新建int[]数组,长度n
//再存到变量a
int[] a = new int[n];
//遍历数组,填入100内随机整数
for (int i = 0; i < a.length; i++) {
a[i] = new Random().nextInt(100);
}
//返回数组a
return a;
}
private static int binarySearch(int[] a, int t) {
/*
* t = 36
* mid
* [16, 21, 30, 36, 39, 70, 70, 92]
* lo
* hi
* *) lo和hi关系 lo<=hi
* *) 交叉就是找不到数据
* *) lo位置是插入点位置
*
* *)定义三个下标值
* lo=0, hi=a.length-1
* mid 只定义先不赋值
* *)循环,当lo<=hi
* *)计算中间下表存到 mid
* *)如果a[mid]<t,lo定位到mid+1
* *)否则如果a[mid]>t,hi定义到mid-1
* *)否则,返回mid的值
* *)lo、hi交叉结束
* 返回 -(lo+1),表示-(插入点+1)
*/
int lo = 0;
int hi = a.length-1;
int mid;
while(lo <= hi) {
mid = (lo+hi) / 2;
if(a[mid] < t) {
lo = mid+1;
} else if(a[mid] > t) {
hi = mid-1;
} else {
return mid;
}
}
//避免lo是0,加1后,再加负号
return -(lo+1); // -(插入点+1)
}
}
1.8 练习:有序数组的并归
项目:有序数组并归
package shuzu;
import java.util.Arrays;
import java.util.Random;
public class 有序数组并归 {
public static void main(String[] args) {
int[] a = suiji();
Arrays.sort(a);
System.out.println(Arrays.toString(a));
int[] b = suiji();
Arrays.sort(b);
System.out.println(Arrays.toString(b));
int[] arr = hebing(a,b);
System.out.println(Arrays.toString(arr));
}
private static int[] hebing(int[] a, int[] b) {
/*
* a[1,1,2,3,4]
* j
* b[1,2,4,5,6,8,9]
* k
*
* c[ ]
* i
*/
int j=0,k=0;
int[] temp = new int[a.length+b.length];
for (int i =0;i<temp.length;i++) {
if(j>=a.length) {
//j越界,b数组数据一个一个放入新数组
//c[i] = b[k];
//k++;
//continue;
System.arraycopy(b, k, temp, i, b.length-k);
break;
}
if(k>=b.length) {
//k越界,a数组数据一个个放入新数组
//c[i] = a[j];
//j++;
//continue;
System.arraycopy(a, j, temp, i, a.length-j);
break;
}
//j和k,较小值放入i位置,并递增
if(a[j]<=b[k]) {
temp[i] = a[j];
j++;
}else {
temp[i] = b[k];
k++;
}
}
return temp;
}
private static int[] suiji() {
int n = 5+new Random().nextInt(5);
int[] arr = new int[n];
for(int i = 0;i<arr.length;i++) {
arr[i] = new Random().nextInt(100);
}
return arr;
}
}
1.9 练习:双色球
红球33选6
蓝球16选1
package day0801;
import java.util.Arrays;
import java.util.Random;
public class Test1 {
public static void main(String[] args) {
//准备两个号码数组
int[] r = zbsz(33);//[1,2,3,4,5....33]
int[] b = zbsz(16);//[1,2,3...16]
System.out.println(Arrays.toString(r));
System.out.println(Arrays.toString(b));
//选择红球
int[] red = selectRed(r);
//选择蓝球
int blue = selectBlue(b);
System.out.println("红球:"+Arrays.toString(red));
System.out.println("蓝球:"+blue);
}
private static int[] zbsz(int n) {
//新建n个长度的int[]数组,存到a
int[] a = new int[n];
//遍历a数组,填入1到n
for (int i = 0; i < a.length; i++) {
a[i] = i+1;
}
//返回数组
return a;
}
private static int[] selectRed(int[] r) {
/*
* j
* r [10, 5, 1, 4, 2, 6, 7, 8, 9, 3, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]
* i
*
* [i, r.length)
* i+ [0, r.length-i)
*/
//i循环从0到6
for (int i = 0; i < 6; i++) {
//j随机定位
int j = i+ new Random().nextInt(r.length-i);
int t = r[i];// 元素交换
r[i] = r[j];
r[j] = t;
}
//截取前6个位置,生成一个新数组返回
return Arrays.copyOf(r, 6);
}
private static int selectBlue(int[] b) {
return b[new Random().nextInt(16)];
}
}
二、java.util.Arrays 工具类
- 数组工具类
- 提供几个数组操作的工具方法
• Arrays.toString(a)
把数组中的数据,一个一个连接成字符串
"[值1, 值2, 值3, 值4]"
• Arrays.sort(a)
数组排序
基本类型数组,优化的快速排序
引用类型数组,优化的合并排序
- Arrays.binarySearch(a, t)
二分法查找、折半查找:在有序数组中,查找目标值的位置下标。若找不到目标值,返回 -(插入点+1)。
- Arrays.copyOf(a, 指定长度)
把数组,复制成指定长度的新数组
三、数组复制
• Arrays.copyOf()
会新建数组
- System.arraycopy( 原数组, 原数组起始位置, 目标数组, 目标数组起始位置, 复制的数据数量)
不会新建数组
四、二维数组
4.1 概述
- 数组中,放数组
4.1.1 二维数组创建
• int[][] a = new int[3][2];
外围数组长度3
内部三个数组,长度2
共创建了4个数组
内部数组存放默认值0
外围数组存放内部数组的地址
- int[][] a = new int[3][];
只创建了1个外围数组
存放null(空)值
可以之后再创建数组放入外围数组
a[0] = new int[4];
a[1] = new int[]{1,2,1};
a[2] = new int[]{5,2,6,2,3};
• n int[][] a = { {4,3,2,6}, {5,2,3,6,2}, {7,3,1} };
4.1.2 二位数组遍历
for(int i=0;i<a.length;i++) {
for(int j=0;j<a[i].length;j++) {
a[i][j]
}
}
4.2 练习:二维数组
项目:二维数组
类:Test1
package day0602;
public class Test1 {
public static void main(String[] args) {
char[][] a = {
//i
/*0*/{'道','路','千','万','条'},
/*1*/{'安','全','第','一','条'},
/*2*/{'行','车','不','规','范'},
/*3*/{'亲','人','两','行','泪'}
//0 1 2 3 4 j
};
/* j是外层循环,递增
* i是内层循环,递减
*
* 亲行安道
* 人车全路
* 两不第千
*/
for(int j=0;j<a[0].length;j++) {
for(int i=a.length-1; i>=0; i--) {
System.out.print(a[i][j]);
}
System.out.println();
}
}
}