数组进阶
Last updated
Was this helpful?
Last updated
Was this helpful?
System类中提供arraycopy方法来进行数组拷贝。
源码:
src:目标数组
srcPos:从目标数组的某下标位置开始拷贝
dest:新数组
destPos:从新数组的某下标位置开始存放。
Length:(从目标数组的某下标位置开始拷贝)指定将目标数组的多少个元素赋给新数组的元素。
代码:
public static void main(String[] args) {
TestArray.copyTest();
}
public static void copyTest(){
int[] aa = {11,22,33,44,55,66};
int[] bb = new int[8];
// 从数组aa的下标2位置开始拷贝4个元素给bb数组,并从bb数组的下标3位置开始存放。
System.arraycopy(aa, 2, bb, 3, 4);
for(int i=0; i<bb.length; i++){
System.out.println(i+"--"+bb[i]);
}
}
效果:
示例:
public class CopyArr {
public static void main(String[] args){
//删除
String[] s = {"aa","bb","cc","dd","ee"};
del(s,1);
insert(s, 5,"ff");
}
//删除任意位置的一个元素,并打印新数组
public static void del(String[] s, int index){
String[] s1 = new String[s.length-1];
//拷贝两次,一次是从index前面的下标开始拷贝,一次是从index后面的下标开始拷贝
//前面
System.arraycopy(s,0,s1,0,index);
//后面
System.arraycopy(s,index+1,s1,index,s1.length-index);
System.out.println(Arrays.toString(s1));
}
//插入任意位置的一个元素,并打印新数组 str代表插入内容,index代表插入下标
public static void insert(String[] s, int index, String str){
String[] s1 = new String[s.length+1];
//插入内容到新数组
s1[index] = str;
//也是拷贝两次,一次前面,一次后面
System.arraycopy(s,0,s1,0,index);//前面
System.arraycopy(s,index,s1,index+1,s.length-index);//后面
System.out.println(Arrays.toString(s1));
}
}
效果:
代码:
String[] s = {"成都","重庆","上海","北京","天津"};
TestArray.copyTest1(s, 2);
}
// 删除数组s的指定元素index,并把原数组返回。
public static void copyTest1(String[] s, int index){
/*从数组aa的下标index后一位的位置开始index+1拷贝s.length-index-1个元素给aa数组,
并从aa数组的下标index位置开始存放。*/
System.arraycopy(s, index+1, s, index, s.length-index-1);
// 下标s.length-1的值还是原来的值,我们要把它赋值为空,如果不这样做,运行会出现s[s.length-1]的值与s[s.length-2]的值一样
s[s.length-1] = null;
for(int i=0; i<s.length; i++){
System.out.println(i+"--"+s[i]);
}
}
效果:
代码:
TestArray.copyTest2();
}
// 把数组原封不动的转移到一个更大的数组上。
public static void copyTest2(){
int[] aa = {11,22,33,44,55,66};
int[] bb = new int[8];
System.arraycopy(aa, 0, bb, 0, aa.length);
for(int i=0; i<bb.length; i++){
System.out.println(i+"--"+bb[i]);
}
}
效果:
完整代码:
package com.itcode.demo2;
/**
* @author: 成都码到功成学员
* @Description:
* 数组拷贝
*/
public class TestArray {
public static void main(String[] args) {
// TestArray.copyTest();
// String[] s = {"成都","重庆","上海","北京","天津"};
// TestArray.copyTest1(s, 2);
TestArray.copyTest2();
}
// 把数组原封不动的转移到一个更大的数组上。
public static void copyTest2(){
int[] aa = {11,22,33,44,55,66};
int[] bb = new int[8];
System.arraycopy(aa, 0, bb, 0, aa.length);
for(int i=0; i<bb.length; i++){
System.out.println(i+"--"+bb[i]);
}
}
// 删除数组s的指定元素index,并把原数组返回。
public static void copyTest1(String[] s, int index){
/*从数组aa的下标index后一位的位置开始index+1拷贝s.length-index-1个元素给aa数组,
并从aa数组的下标index位置开始存放。*/
System.arraycopy(s, index+1, s, index, s.length-index-1);
// 下标s.length-1的值还是原来的值,我们要把它赋值为空,如果不这样做,运行会出现s[s.length-1]的值与s[s.length-2]的值一样
s[s.length-1] = null;
for(int i=0; i<s.length; i++){
System.out.println(i+"--"+s[i]);
}
}
public static void copyTest(){
int[] aa = {11,22,33,44,55,66};
int[] bb = new int[8];
// 从数组aa的下标2位置开始拷贝4个元素给bb数组,并从bb数组的下标3位置开始存放。
System.arraycopy(aa, 2, bb, 3, 4);
for(int i=0; i<bb.length; i++){
System.out.println(i+"--"+bb[i]);
}
}
}
这里再增加一个插入
int[] a = {11,22,33,44,55,66};
int[] b = new int[a.length+1];
System.out.println(b.length);
System.arraycopy(a, 0, b, 0, a.length);
System.out.println(Arrays.toString(b));
System.out.println("==============================");
System.arraycopy(b,3 ,b, 4, b.length-4);
b[3] = 5;
System.out.println(Arrays.toString(b));
效果:
主要方法是打印toString(),填充fill(),排序sort(),二分查找binarySearch()。
代码:
package com.itcode.demo2;
import java.util.Arrays;
/**
* @author: 成都码到功成学员
* @Description:
* Arrays工具类
*/
public class TestArray2 {
public static void main(String[] args) {
int[] a = {2,3544,454,323,2,3,234,23,43,231};
System.out.println("排序前:"+ Arrays.toString(a));
Arrays.sort(a);
System.out.println("排序前:"+ Arrays.toString(a));
System.out.println(Arrays.binarySearch(a, 23));// 返回23的下标
Arrays.fill(a,2,4, 888);
System.out.println("填充后 :"+ Arrays.toString(a));
}
}
效果:
实例:
package com.itcode.demo2;
import java.util.Arrays;
/**
* @author: 成都码到功成学员
* @Description:
* 引用类型排序
* Comparable<ArrayTest3>里面的ArrayTest3是泛型。
*/
class ArrayTest3 implements Comparable<ArrayTest3>{
String name;
int age;
public ArrayTest3(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "ArrayTest3{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(ArrayTest3 o) {
// 按年龄比较
if(this.age>o.age){
return 1;
}
return 0;
}
}
public class TestArray3 {
public static void main(String[] args) {
ArrayTest3[] o = {
new ArrayTest3("成都", 3),
new ArrayTest3("北京", 5),
new ArrayTest3("上海", 2),
new ArrayTest3("深圳", 4)};
Arrays.sort(o);
System.out.println(Arrays.toString(o));
}
}
效果:
多维数组中,一般最多用到二维数组。工作中很少用到数组,都是用容器,所以这一节了解即可。
二维数组的内存空间
比如我们定义一个二维数组:int[][] a = new int[3]2。创建一个总的对象,有三个值a[0][…]、a[1][…]、a[2][…],然后这三个变量的值分别引用一维数组对象的地址值。
实例:
package com.itcode.demo2;
import java.util.Arrays;
/**
* @author: 成都码到功成学员
* @Description:
* 引用类型排序
* Comparable<ArrayTest3>里面的ArrayTest3是泛型。
*/
public class TestArray4 {
public static void main(String[] args) {
// 二维数组静态初始化。
int[][] a = {
{2,3,4},
{2,1,2,3,45,56,4},
{2,34,4}
};
// 二维数组动态初始化。
int[][] b = new int[2][0];
// 数组测试 注意:这儿20170210并不是基本类,java编译器会把基本类包装成引用类型。
Object[][] o = new Object[4][];
o[0] = new Object[]{3, "张亮", "java", 20170210};
o[1] = new Object[]{6, "王集", "Android", 20180210};
o[2] = new Object[]{1, "陈丽", "UI", 20170310};
o[3] = new Object[]{4, "周动", "IOS", 20160210};
for(int i=0; i<o.length; i++){
System.out.println(Arrays.toString(o[i]));
}
}
}
效果:
两两比较大小,大的往后,小的放前,交换位置。第一次循环比较完毕,最大的出现在最后面;第二次循环比较完毕,第二大的出现在最后面;依次类推,到最后一次比较完毕,从小到大依次排序。假如一个数组有N个元素,冒泡排序最多要比较1+2+3+……+n-1次,也就是(n-2)(n-1)/2次(请看初中数学)判断交换才把一组数字完全无误的比较从大到小出来。
代码:
public static void main(String[] args) {
int[] aa = {7,34,23,45,1,46,34,2,6,3,9,8,5};
TestArray5.bubbleSort(aa);
}
public static void bubbleSort(int[] arr){
// 外循环
for(int a=1;a<arr.length+1;a++){
System.out.println("第" + a + "次循环");
// 内循环
for(int b=0; b<arr.length-a; b++) {
// 两个整数交换
if (arr[b] > arr[b + 1]) {
int temp = arr[b];
arr[b] = arr[b + 1];
arr[b + 1] = temp;
}
System.out.println(Arrays.toString(arr));
}
System.out.println("第" + a + "次循环比较的最终结果:"+Arrays.toString(arr));
}
}
结果:
第1次循环
[7, 34, 23, 45, 1, 46, 34, 2, 6, 3, 9, 8, 5]
[7, 23, 34, 45, 1, 46, 34, 2, 6, 3, 9, 8, 5]
[7, 23, 34, 45, 1, 46, 34, 2, 6, 3, 9, 8, 5]
[7, 23, 34, 1, 45, 46, 34, 2, 6, 3, 9, 8, 5]
[7, 23, 34, 1, 45, 46, 34, 2, 6, 3, 9, 8, 5]
[7, 23, 34, 1, 45, 34, 46, 2, 6, 3, 9, 8, 5]
[7, 23, 34, 1, 45, 34, 2, 46, 6, 3, 9, 8, 5]
[7, 23, 34, 1, 45, 34, 2, 6, 46, 3, 9, 8, 5]
[7, 23, 34, 1, 45, 34, 2, 6, 3, 46, 9, 8, 5]
[7, 23, 34, 1, 45, 34, 2, 6, 3, 9, 46, 8, 5]
[7, 23, 34, 1, 45, 34, 2, 6, 3, 9, 8, 46, 5]
[7, 23, 34, 1, 45, 34, 2, 6, 3, 9, 8, 5, 46]
第1次循环比较的最终结果:[7, 23, 34, 1, 45, 34, 2, 6, 3, 9, 8, 5, 46]
第2次循环
[7, 23, 34, 1, 45, 34, 2, 6, 3, 9, 8, 5, 46]
[7, 23, 34, 1, 45, 34, 2, 6, 3, 9, 8, 5, 46]
[7, 23, 1, 34, 45, 34, 2, 6, 3, 9, 8, 5, 46]
[7, 23, 1, 34, 45, 34, 2, 6, 3, 9, 8, 5, 46]
[7, 23, 1, 34, 34, 45, 2, 6, 3, 9, 8, 5, 46]
[7, 23, 1, 34, 34, 2, 45, 6, 3, 9, 8, 5, 46]
[7, 23, 1, 34, 34, 2, 6, 45, 3, 9, 8, 5, 46]
[7, 23, 1, 34, 34, 2, 6, 3, 45, 9, 8, 5, 46]
[7, 23, 1, 34, 34, 2, 6, 3, 9, 45, 8, 5, 46]
[7, 23, 1, 34, 34, 2, 6, 3, 9, 8, 45, 5, 46]
[7, 23, 1, 34, 34, 2, 6, 3, 9, 8, 5, 45, 46]
第2次循环比较的最终结果:[7, 23, 1, 34, 34, 2, 6, 3, 9, 8, 5, 45, 46]
第3次循环
[7, 23, 1, 34, 34, 2, 6, 3, 9, 8, 5, 45, 46]
[7, 1, 23, 34, 34, 2, 6, 3, 9, 8, 5, 45, 46]
[7, 1, 23, 34, 34, 2, 6, 3, 9, 8, 5, 45, 46]
[7, 1, 23, 34, 34, 2, 6, 3, 9, 8, 5, 45, 46]
[7, 1, 23, 34, 2, 34, 6, 3, 9, 8, 5, 45, 46]
[7, 1, 23, 34, 2, 6, 34, 3, 9, 8, 5, 45, 46]
[7, 1, 23, 34, 2, 6, 3, 34, 9, 8, 5, 45, 46]
[7, 1, 23, 34, 2, 6, 3, 9, 34, 8, 5, 45, 46]
[7, 1, 23, 34, 2, 6, 3, 9, 8, 34, 5, 45, 46]
[7, 1, 23, 34, 2, 6, 3, 9, 8, 5, 34, 45, 46]
第3次循环比较的最终结果:[7, 1, 23, 34, 2, 6, 3, 9, 8, 5, 34, 45, 46]
第4次循环
[1, 7, 23, 34, 2, 6, 3, 9, 8, 5, 34, 45, 46]
[1, 7, 23, 34, 2, 6, 3, 9, 8, 5, 34, 45, 46]
[1, 7, 23, 34, 2, 6, 3, 9, 8, 5, 34, 45, 46]
[1, 7, 23, 2, 34, 6, 3, 9, 8, 5, 34, 45, 46]
[1, 7, 23, 2, 6, 34, 3, 9, 8, 5, 34, 45, 46]
[1, 7, 23, 2, 6, 3, 34, 9, 8, 5, 34, 45, 46]
[1, 7, 23, 2, 6, 3, 9, 34, 8, 5, 34, 45, 46]
[1, 7, 23, 2, 6, 3, 9, 8, 34, 5, 34, 45, 46]
[1, 7, 23, 2, 6, 3, 9, 8, 5, 34, 34, 45, 46]
第4次循环比较的最终结果:[1, 7, 23, 2, 6, 3, 9, 8, 5, 34, 34, 45, 46]
第5次循环
[1, 7, 23, 2, 6, 3, 9, 8, 5, 34, 34, 45, 46]
[1, 7, 23, 2, 6, 3, 9, 8, 5, 34, 34, 45, 46]
[1, 7, 2, 23, 6, 3, 9, 8, 5, 34, 34, 45, 46]
[1, 7, 2, 6, 23, 3, 9, 8, 5, 34, 34, 45, 46]
[1, 7, 2, 6, 3, 23, 9, 8, 5, 34, 34, 45, 46]
[1, 7, 2, 6, 3, 9, 23, 8, 5, 34, 34, 45, 46]
[1, 7, 2, 6, 3, 9, 8, 23, 5, 34, 34, 45, 46]
[1, 7, 2, 6, 3, 9, 8, 5, 23, 34, 34, 45, 46]
第5次循环比较的最终结果:[1, 7, 2, 6, 3, 9, 8, 5, 23, 34, 34, 45, 46]
第6次循环
[1, 7, 2, 6, 3, 9, 8, 5, 23, 34, 34, 45, 46]
[1, 2, 7, 6, 3, 9, 8, 5, 23, 34, 34, 45, 46]
[1, 2, 6, 7, 3, 9, 8, 5, 23, 34, 34, 45, 46]
[1, 2, 6, 3, 7, 9, 8, 5, 23, 34, 34, 45, 46]
[1, 2, 6, 3, 7, 9, 8, 5, 23, 34, 34, 45, 46]
[1, 2, 6, 3, 7, 8, 9, 5, 23, 34, 34, 45, 46]
[1, 2, 6, 3, 7, 8, 5, 9, 23, 34, 34, 45, 46]
第6次循环比较的最终结果:[1, 2, 6, 3, 7, 8, 5, 9, 23, 34, 34, 45, 46]
第7次循环
[1, 2, 6, 3, 7, 8, 5, 9, 23, 34, 34, 45, 46]
[1, 2, 6, 3, 7, 8, 5, 9, 23, 34, 34, 45, 46]
[1, 2, 3, 6, 7, 8, 5, 9, 23, 34, 34, 45, 46]
[1, 2, 3, 6, 7, 8, 5, 9, 23, 34, 34, 45, 46]
[1, 2, 3, 6, 7, 8, 5, 9, 23, 34, 34, 45, 46]
[1, 2, 3, 6, 7, 5, 8, 9, 23, 34, 34, 45, 46]
第7次循环比较的最终结果:[1, 2, 3, 6, 7, 5, 8, 9, 23, 34, 34, 45, 46]
第8次循环
[1, 2, 3, 6, 7, 5, 8, 9, 23, 34, 34, 45, 46]
[1, 2, 3, 6, 7, 5, 8, 9, 23, 34, 34, 45, 46]
[1, 2, 3, 6, 7, 5, 8, 9, 23, 34, 34, 45, 46]
[1, 2, 3, 6, 7, 5, 8, 9, 23, 34, 34, 45, 46]
[1, 2, 3, 6, 5, 7, 8, 9, 23, 34, 34, 45, 46]
第8次循环比较的最终结果:[1, 2, 3, 6, 5, 7, 8, 9, 23, 34, 34, 45, 46]
第9次循环
[1, 2, 3, 6, 5, 7, 8, 9, 23, 34, 34, 45, 46]
[1, 2, 3, 6, 5, 7, 8, 9, 23, 34, 34, 45, 46]
[1, 2, 3, 6, 5, 7, 8, 9, 23, 34, 34, 45, 46]
[1, 2, 3, 5, 6, 7, 8, 9, 23, 34, 34, 45, 46]
第9次循环比较的最终结果:[1, 2, 3, 5, 6, 7, 8, 9, 23, 34, 34, 45, 46]
第10次循环
[1, 2, 3, 5, 6, 7, 8, 9, 23, 34, 34, 45, 46]
[1, 2, 3, 5, 6, 7, 8, 9, 23, 34, 34, 45, 46]
[1, 2, 3, 5, 6, 7, 8, 9, 23, 34, 34, 45, 46]
第10次循环比较的最终结果:[1, 2, 3, 5, 6, 7, 8, 9, 23, 34, 34, 45, 46]
第11次循环
[1, 2, 3, 5, 6, 7, 8, 9, 23, 34, 34, 45, 46]
[1, 2, 3, 5, 6, 7, 8, 9, 23, 34, 34, 45, 46]
第11次循环比较的最终结果:[1, 2, 3, 5, 6, 7, 8, 9, 23, 34, 34, 45, 46]
第12次循环
[1, 2, 3, 5, 6, 7, 8, 9, 23, 34, 34, 45, 46]
第12次循环比较的最终结果:[1, 2, 3, 5, 6, 7, 8, 9, 23, 34, 34, 45, 46]
第13次循环
第13次循环比较的最终结果:[1, 2, 3, 5, 6, 7, 8, 9, 23, 34, 34, 45, 46]
看结果是不是有13个数字第一次循环比较了12次,第二次循环比较了11次,……第12次就比较了一次,总共比较了156次。
之前我们说过是一个拥有N个元素的数组最多需要(n-1)n次可以循环处理结果。然后注意再看结果
在第9次循环的最后一次比较排序结果就已经完全出来了。
所以我们要做优化
public static void bubbleSort(int[] arr){
// 外循环
for(int a=1;a<arr.length+1;a++){
boolean flag = true;
System.out.println("第" + a + "次循环");
// 内循环
for(int b=0; b<arr.length-a; b++) {
// 两个整数交换
if (arr[b] > arr[b + 1]) {
int temp = arr[b];
arr[b] = arr[b + 1];
arr[b + 1] = temp;
// 如果发生了交换,flag就变为false
flag = false;
}
System.out.println(Arrays.toString(arr));
}
// 如果没有发生位置交换,证明数组已经排序完毕,跳出循环。
if(flag){
break;
}
System.out.println("第" + a + "次循环比较的最终结果:"+Arrays.toString(arr));
}
}
效果:
完整代码:
package com.itcode.demo2;
import java.util.Arrays;
/**
* @author: 成都码到功成学员
* @Description:
* 冒泡排序
*/
public class TestArray5 {
public static void main(String[] args) {
int[] aa = {7,34,23,45,1,46,34,2,6,3,9,8,5};
TestArray5.bubbleSort1(aa);
}
// 正式面试这样写即可
public static void bubbleSort1(int[] arr){
for(int a=0; a<arr.length-1; a++){
boolean flag = true;
for (int b=0;b<arr.length-a-1; b++){
// if(arr[b+1] < arr[b]){// 升序排序
if(arr[b] < arr[b+1]){// 降序排序
int temp = arr[b];
arr[b] = arr[b+1];
arr[b+1] = temp;
flag = false;
}
}
}
System.out.println(Arrays.toString(arr));
}
// 这个方法主要是为了让大家看懂,所以多打印一些东西
public static void bubbleSort(int[] arr){
// 外循环
for(int a=1;a<arr.length+1;a++){
boolean flag = true;
System.out.println("第" + a + "次循环");
// 内循环
for(int b=0; b<arr.length-a; b++) {
// 两个整数交换
if (arr[b] > arr[b + 1]) {
int temp = arr[b];
arr[b] = arr[b + 1];
arr[b + 1] = temp;
// 如果发生了交换,flag就变为false
flag = false;
}
System.out.println(Arrays.toString(arr));
}
// 如果没有发生位置交换,证明数组已经排序完毕,跳出循环。
if(flag){
break;
}
System.out.println("第" + a + "次循环比较的最终结果:"+Arrays.toString(arr));
}
}
}
概述:第一次排序会把后面的每一个元素和第一个元素比较,如果比第一个元素小,就把交换位置,第一次比较完毕,最小的值出现在第一位。接下来又是第二个元素和后面的元素一一比较…比较完毕,第二小的值出现在第二位。以此类推,到最后一位比较完毕,得到一个升序数组。数组长度是几就比较几次。
如:数组 int[] arr={5,2,8,4,9,1};下面是五次比较结果
1 2 8 4 9 5
1 2 8 4 9 5
1 2 4 8 9 5
1 2 4 5 9 8
1 2 4 5 8 9
示例:
// 选择排序
public static void test10(){
int[] a = {36,43,74,24,27};
for(int i=0;i<a.length-1;i++){
for(int j=i+1;j<a.length;j++){
//if(a[j]<a[i]){//升序
if(a[j]>a[i]){//降序
int t = a[j];
a[j] = a[i];
a[i] = t;
}
}
}
System.out.println(Arrays.toString(a));
}
前提:排序好
概括:把一个数字从升序排序好的一组数字之间最中间那个数进行比较,如果等于,之间返回此数字下标;如果大于,就从这个中间数字的后一位和最后一位的中间位置再进行比较;
如果小于,就从这个中间数字的前一位和最前一位的中间位置再进行比较。如此反复,直到找完为止,找到返回,没有找到符合的值,报错。
实例:
package com.itcode.demo2;
import java.util.Arrays;
/**
* @author: 成都码到功成学员
* @Description:
* 二分查找
*/
public class TestArray6 {
public static void main(String[] args) {
int[] aa = {7,34,23,45,1,46,2,6,3,9,8,5};
Arrays.sort(aa);
System.out.println(Arrays.toString(aa));
System.out.println(TestArray6.binarySearch(aa, 5));
}
// arr数组,a要查的值
public static int binarySearch(int[] arr, int a){
int start = 0;
int end = arr.length-1;
while (start <= end){
int mid = (start+end)/2;
if(a == arr[mid]){
return mid;
}
if(a < arr[mid]){
end = mid - 1;
}
if(a > arr[mid]){
start = mid + 1;
}
}
return -1;
}
}
效果:
代码:
// 杨辉三角
public static void test11(){
// 设定外层值 10
int[][] a = new int[10][];
for(int i=0;i<a.length;i++){
//为一维数组分配空间
a[i] = new int[i+1];
for(int j=0;j<a[i].length;j++){
// 打印两边外层1
if(j==0 || j== a[i].length-1){
a[i][j] = 1;
System.out.print(a[i][j] + "\t");
}else {
// 打印中心值
a[i][j] = a[i-1][j-1]+a[i-1][j];
System.out.print(a[i][j]+"\t");
}
}
// 换行
System.out.println();
}
}