一、数组拷贝调用方法
(1)一维数组for循环拷贝
package demo;
import java.util.Arrays;
class TestArray{
private int val = 3;
public void setVal(int val){
this.val = val;//this引用类的当前实例,只能在构造方法、实力初始化代码块和实例方法中使用,直接访问实例字段。静态成员方法中不能使用this关键字。
}
public int getVal(int Val){
return this.val;
}
}
public class Test1017_for {
public static void main(String[] args){
TestArray[] t1 = new TestArray[4];//创建长度为4的数组t1
t1[0] = new TestArray();
t1[1] = new TestArray();
t1[2] = new TestArray();
t1[3] = new TestArray();
TestArray[] t2 = new TestArray[4];
for(int i = 0;i < t1.length;i ++){
t2[i] = t1[i];
}
//打印两个数组
for(int i = 0;i < t1.length;i ++){
System.out.print(t1[i].getVal(1) + " ");
}
System.out.println();
for(int i = 0;i < t2.length;i ++) {
System.out.print(t2[i].getVal(1) + " ");
}
System.out.println();
t2[0].setVal(10000);//更改t2[0]的值看t1有没有变化,运行后t1也改变,for循环是浅拷贝
System.out.println("===========");
for(int i = 0;i < t1.length;i ++){
System.out.print(t1[i].getVal(1) + " ");
}
System.out.println();
for(int i = 0;i < t2.length;i ++) {
System.out.print(t2[i].getVal(1) + " ");
}
// //for循环数组
// int[] a_array = {1,2,3,4,5,6,7,8,9};
// int[] b_array = new int[a_array.length];
// for(int i = 0;i < a_array.length;i ++){
// b_array[i] = a_array[i];
// }
// System.out.println(Arrays.toString(a_array));
// System.out.println(Arrays.toString(b_array));
// b_array[0] = 10000;
// System.out.println("===========");
// System.out.println(Arrays.toString(a_array));
// System.out.println(Arrays.toString(b_array));
}
}
(2)数组名.clone()——浅拷贝
package demo;
import java.util.Arrays;
class TestArray1{
private int val = 2;
public void setVal(int val){
this.val = val;
}
public int getVal(int val){
return this.val;
}
}
public class Test1017_array_clone {
public static void main(String[] args) {
TestArray1[] t1 = new TestArray1[4];
t1[0] = new TestArray1();
t1[1] = new TestArray1();
t1[2] = new TestArray1();
t1[3] = new TestArray1();
TestArray1[] t2 = t1.clone();
for(int i = 0;i < t1.length;i ++){
System.out.print(t1[i].getVal(1) + " ");
}
System.out.println();
for(int i = 0;i < t1.length;i ++){
System.out.print(t2[i].getVal(1) + " ");
}
System.out.println();
t2[0].setVal(10000);
System.out.println("==================");
for(int i = 0;i < t1.length;i ++){
System.out.print(t1[i].getVal(1) + " ");
}
System.out.println();
for(int i = 0;i < t1.length;i ++){
System.out.print(t2[i].getVal(1) + " ");
}
// int[] a = {1,2,3,4,5,6,7,8,9};
// int[] b = a.clone();
// System.out.println(Arrays.toString(a));
// System.out.println(Arrays.toString(b));
// b[0] = 10000;
// System.out.println("================");
// System.out.println(Arrays.toString(a));
// System.out.println(Arrays.toString(b));
}
}
(3)System.arraycopy()——浅拷贝
1.是一个本地的方法,源码中定义如下:
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
2.当使用这个方法时,复制到的数组是已经分配内存单元的。
package demo;
import java.util.Arrays;
class TestArray2{
private int val = 2;
public void setVal(int val){
this.val = val;
}
public int getVal(int val){
return this.val;
}
}
public class Test1017_System_arraycopy {
public static void main(String[] args) {
TestArray2[] t1 = new TestArray2[5];
t1[0] = new TestArray2();
t1[1] = new TestArray2();
t1[2] = new TestArray2();
t1[3] = new TestArray2();
t1[4] = new TestArray2();
TestArray2[] t2 = new TestArray2[t1.length];
System.arraycopy(t1,0,t2,0,t1.length);
for(int i = 0;i < t1.length;i ++){
System.out.print(t1[i].getVal(1) + " ");
}
System.out.println();
for(int i = 0;i < t1.length;i ++){
System.out.print(t2[i].getVal(1) + " ");
}
System.out.println();
t2[0].setVal(10000);
System.out.println("==================");
for(int i = 0;i < t1.length;i ++){
System.out.print(t1[i].getVal(1) + " ");
}
System.out.println();
for(int i = 0;i < t1.length;i ++){
System.out.print(t2[i].getVal(1) + " ");
}
// int[] a = {1,2,3,4,5};
// int[] b = new int[a.length];
// System.arraycopy(a,0,b,0,a.length);
// System.out.println(Arrays.toString(a));
// System.out.println(Arrays.toString(b));
}
}
(4)Array.copyOf()——浅拷贝
底层调用System.arraycopy()
package demo;
import java.util.Arrays;
class TestArray3{
private int val = 2;
public void setVal(int val){
this.val = val;
}
public int getVal(int val){
return this.val;
}
}
public class Test1017_Arrays_copyOf {
public static void main(String[] args) {
TestArray3[] t1 = new TestArray3[5];
t1[0] = new TestArray3();
t1[1] = new TestArray3();
t1[2] = new TestArray3();
t1[3] = new TestArray3();
t1[4] = new TestArray3();
TestArray3[] t2 = new TestArray3[t1.length];
System.arraycopy(t1,0,t2,0,t1.length);
for(int i = 0;i < t1.length;i ++){
System.out.print(t1[i].getVal(1) + " ");
}
System.out.println();
for(int i = 0;i < t1.length;i ++){
System.out.print(t2[i].getVal(1) + " ");
}
System.out.println();
t2[0].setVal(10000);
System.out.println("==================");
for(int i = 0;i < t1.length;i ++){
System.out.print(t1[i].getVal(1) + " ");
}
System.out.println();
for(int i = 0;i < t1.length;i ++){
System.out.print(t2[i].getVal(1) + " ");
}
// int[] a = {2,1,4,3};
// int[] b = Arrays.copyOf(a,a.length);
// System.out.println(Arrays.toString(a));
// System.out.println(Arrays.toString(b));
}
}
实现对象的深拷贝:
实现Cloneable接口,并重写clone方法。一个类不实现这个接口直接使用clone方法是编译通不过的。
二、匿名数组
顾名思义,匿名数组就是没有名字的数组
package demo;
import java.util.Arrays;
public class Test1017_AnonymousArray {
//可变参数编程(数组)
public static int sum(int... array){//语法
int sum = 0;
for(int i : array){
sum = sum + i;
}
return sum;
}
public static int sum1(int[] a){
int sum = 0;
for(int i : a){
sum = sum + i;
}
return sum;
}
public static void main(String[] args) {
int[] a = {1,2,3,4,};
System.out.println(sum(a));
System.out.println(sum(1,2));
System.out.println(sum1(a));
/*
int[] array = {1,2,3,4,5};//创建数组对象时就给数组赋值,没有使用new关键字
System.out.println(Arrays.toString(array));//输出:[1, 2, 3, 4, 5]
int[] a = new int[]{1,2,3,4};//创建一个新的数组,根据花括号里面的值对数组进行初始化,数组的长度就是花括号里数据的个数
System.out.println(Arrays.toString(a));//输出:[1, 2, 3, 4]
//在不创建新数组的情况下,重新去初始化一个数组
array = new int[]{5,6,7,8,9};
System.out.println(Arrays.toString(array));//输出:[5, 6, 7, 8, 9]
*/
}
}
三、问题解决
1.二分查找
(1)int mid = (low + high)>>>1;//mid = (low + high) / 2位运算最快
(2)return -(low + 1);//查找失败,返回-(如果存在这个数将会在哪里)
(3)无须数组:先排序后查找
调用方法:Arrays.sort()
int[] array = {3,6,2,1,5};
Arrays.sort(array);//优化后的快速排序
(4)二分查找调用方法Arrays.binarySearch()
2.求连续子数组的最大和
两个嵌套for循环时间复杂度为O(n^2)
int max = Integer.MIN_VALUE;//0x8000 0000
int sum = 0;
for(int i = 0;i < array.length;i ++){
if (sum <= 0){
sum = array[i];
}else{
sum = sum + array[i];
}
if(sum > max){
max = sum;
}
}
return max;
注:所有new得到的对象都放在堆上
四、练习
1.将奇数放在偶数前面,大小顺序不要求
package demo;
import java.util.Arrays;
//将奇数放在偶数前面 大小顺序不要求
public class Demo1019_OddInFrontOfEve {
public static int[] front(int[] array) {
int i = 0;
int j = array.length - 1;//设两个标记,i在数组开始,j在数组最后
while(i< j) {//当i不小于j时,数组遍历结束
while(i < j && array[i] % 2 != 0) {//如果a[i]是奇数,i++,判断下一个数;如果是偶数,需要交换
i ++;
}
while(i < j && array[j] % 2 == 0) {//如果a[i]是偶数,j--,判断前一个数;如果是奇数,需要交换
j --;
}
if(i < j){//交换偶数和奇数的位置
int t = array[i];
array[i] = array[j];
array[j] = t;
}
}
return array;
}
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6,7};
System.out.println(Arrays.toString(front(array)));
}
}
2.一个数组是有序的,给定一个key:数字,有两个数字的和加起来等于key,找到这两个数字的下标,时间复杂度O(n)
package demo;
import java.util.Arrays;
//一个数组是有序的,给定一个key:数字,有两个数字的和加起来等于key,找到这两个数字的下标,时间复杂度O(n)
public class Demo1019_SumKey {
public static int[] sumKey(int[] array,int key) {
int[] result = new int[2];
int i = 0;
int j = array.length - 1;
int sum = 0;
while(i < j) {
sum = array[i] + array[j];
if(sum < key){
i ++;
}else if(sum > key){
j --;
}else{
result[0] = i;
result[1] = j;
break;
}
}
return result;
}
public static void main(String[] args) {
int[] array = {0,1,2,3,4,5};
System.out.println(Arrays.toString(sumKey(array,6)));
}
}
3.在一个数组的指定位置插入某个元素
package demo;
import java.util.Arrays;
//在一个数组的指定位置插入某个元素
public class Demo1019_Insert {
public static int[] insert(int[] array,int key,int index){
int[] array_1 = new int[array.length + 1];//创建一个长度为array.length+1的数组用于存放插入一个元素之后的数组
System.arraycopy(array,0,array_1,0,index);//把要插入位置之前的index个元素复制到新的数组中
array_1[index] = key;//将一个元素插入到该位置
System.arraycopy(array,index,array_1,index + 1,array.length - index);//将插入位置后面的array.length - index个元素复制到array_1[index]后
return array_1;
}
public static void main(String[] args) {
int[] array = {2,2,2,2,2,2};
System.out.println(Arrays.toString(insert(array,100,2)));
}
}
4.搜索数组中的最小值和最大元素
package demo;
import java.util.Arrays;
//搜索数组中的最小值和最大元素
public class Demo1019_SearchMinAndMax {
public static int[] minAndMax(int[] array){
//查找开始之前,最小值和最大值都是a[0]
int min = array[0];
int max = array[0];
int[] result = new int[2];//创建一个长度为2的数组存放找到的最小值和最大值
for(int i = 0;i < array.length;i ++){
if(array[i] < min){//当a[i]比之前的min小,将a[i]赋给min
min = array[i];
}else if(array[i] > max){//当a[i]比之前的max大,将a[i]赋给max
max = array[i];
}
}
//将查找结果放入结果数组内并返回结果数组
result[0] = min;
result[1] = max;
return result;
}
public static void main(String[] args) {
int[] array = {3,2,-4,6,1,4};
System.out.println(Arrays.toString(minAndMax(array)));
}
}
5.合并两个数组(合并到一个新的数组)
package demo;
import java.util.Arrays;
//合并两个数组(合并到一个新的数组)
public class Demo1019_ConnectArrays {
public static int[] connect(int[] array_a,int[] array_b){
int[] array_c = new int[array_a.length + array_b.length];//合并后的数组长度等于两个被合并数组长度之和
System.arraycopy(array_a,0,array_c,0,array_a.length);//将第一个数组复制在目的数组内
System.arraycopy(array_b,0,array_c,array_a.length,array_b.length);//将第二个数组复制并跟在第一个数组后面
return array_c;
}
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6,7};
int[] array1 = {11,22,33,44};
int[] array_2 = connect(array,array1);
System.out.println(Arrays.toString(array_2));
}
}
6.填充数组(一次填充,部分填充)
package demo;
import java.util.Arrays;
//填充数组(一次填充,部分填充)
public class Demo1019_FillArray {
public static int[] fillingOnce(int[] array,int key){//一次填充
Arrays.fill(array,key);//将数组所有元素填充为key
return array;
}
public static void main(String[] args) {
int[] array = new int[10];
array[3] = 8;
array[5] = 8;
array[6] = 8;
System.out.println(Arrays.toString(array));
System.out.println(Arrays.toString(fillingOnce(array,11111)));
Arrays.fill(array,2,7,5);//将数组array下标为[2,5)的元素填充为5
System.out.println(Arrays.toString(array));
}
}
7.删除数组指定元素
package demo;
import java.util.Arrays;
//删除数组指定元素
public class Demo1019_Delete {
public static int[] delete(int[] array,int index){
for(int i = index;i < array.length - 1;i ++){//将下标为index的元素之后的元素都被它的后一个元素覆盖掉
array[i] = array[i + 1];
}
array[array.length - 1] = 0;//将最后一个元素赋为0
return array;
}
public static void main(String[] args) {
int[] array = {1,3,5,2,4,6};
System.out.println(Arrays.toString(delete(array,2)));
}
}
8.如何从数组中查找常见的元素
package demo;
import java.util.Arrays;
//如何从数组中查找常见的元素
public class Demo1019_SearchCommonElement {
public static int commen(int[] array,int key){
int index = Arrays.binarySearch(array,key);//在该数组内二分查找所找的元素
if(index >= 0){//该元素存在,返回下标
return index;
}
return -1;//该元素不存在,返回-1
}
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6,3};
System.out.println(commen(array,3));
}
}