4.19Java数组的拷贝

4.19Java数组的拷贝

(JDK源码经常碰到,比如容器的拷贝底层全是数组的拷贝)

概念描述

System类里包含一个static void arraycopy(object src, int srcpos, object dest, int destpos, int length)方法

该方法可以将sec数组里的元素赋值给dest数组的元素

srcpos指定从src数组的第几个元素开始赋值

length参数指定将src数组的多少个元素赋给dest数组的元素

数组拷贝:

public class Test{
   public static void main(String[] args){
       String[] s = {"阿里""百度","头条","京东","虾皮"};
       String[] sBak = new String[6];
       System.arraycopy(s,0,sBak,0,s.length);
       for(int i = 0; i < sBak.length; i++){
           System.out.println(sBak[i] + "\t");
      }
  }
}

arraycopy源码:

    public static native void arraycopy(Object src,  int  srcPos,
                                       Object dest, int destPos,
                                       int length);

说明:

  • native是本地的意思,调用本地方法---C语言写出来的,底层是C语言

  • src指源数组---以那个为基础

  • dest指目标数组---复制到哪去

  • srcPos指从哪开始---第几个数组索引值开始

  • destPos(目标数组不一定要和源数组索引一致)---指的是希望放到目标数组的索引位置

    • 比如说我想把源数组的0号索引值放到目标数组的1号索引处,destPos的值是0---起始位置

  • length指的是从源数组开始copy的位置开始拷贝几个数---1、2、3个

源数组与目标数组不一样的copy:

    /*基本测试*/
   public static void testBasicCopy(){

       /*源数组是字符串数组*/
       String[] s1 = {"aa","bb","cc","dd","ee"};
       /*定义一个目标数组,开辟空间不赋值*/
       String[] s2 = new String[10];
       /*从s1拷贝到s2,拷贝cc和dd*/
       /*
       2号索引
       3个
        */
       System.arraycopy(s1,2,s2,6,3); //native本地方法,c语言写出来的内容

       /*遍历打印数组内容*/
       for (int i = 0; i <= s2.length; i++){
           System.out.println(i + "--" + s2[i]);
      }

       /*Arrays.toString方法打印*/
       System.out.printf(Arrays.toString(s2));

  }

源数组与目标数组一致,并且封装方法---很重要

package com.array;

import java.util.Arrays;

/**
* 测试数组的拷贝
* @author Lucifer
*/
public class TestArrayCopy {
   public static void main(String[] args) {
//       testBasicCopy2();

       /*定义一个数组,调用封装的方法*/
       String[] str = {"Alibaba","Bytedance","Tencent","Baidu"};

       /*调用removeElement删除元素*/
       removeElement(str,3);
  }

   /*基本测试*/
   public static void testBasicCopy(){

       /*源数组是字符串数组*/
       String[] s1 = {"aa","bb","cc","dd","ee"};
       /*定义一个目标数组,开辟空间不赋值*/
       String[] s2 = new String[10];
       /*从s1拷贝到s2,拷贝cc和dd*/
       /*
       2号索引
       3个
        */
       System.arraycopy(s1,2,s2,6,3); //native本地方法,c语言写出来的内容

       /*遍历打印数组内容*/
       for (int i = 0; i <= s2.length; i++){
           System.out.println(i + "--" + s2[i]);
      }

//       /*Arrays.toString方法打印*/
//       System.out.printf(Arrays.toString(s2));

  }

   /*测试从数组中删除某个元素(其本质还是数组的拷贝)*/
   //删除数组中指定索引位置的元素,并将原数组返回
   public static void testBasicCopy2(){

       /*
       删掉cc让dd和ee补到前面去
       拷贝的时候不拷贝cc了
       从s1的3号索引开始拷贝
       从s1的2号索引开始放
       从3开始拷贝的长度是s1的长度-1个数
        */
       String[] s1 = {"aa","bb","cc","dd","ee"};
//       String[] s2 = new String[5];
       System.arraycopy(s1,3,s1,3-1,s1.length-3);
       /*
       srcPos是从3号索引开始拷贝
       destPos是放到2号索引的位置---只是复制过去
       d、e覆盖了c和d,因为最后一位e没有删除,所以还会输出最后一个e
       所以要将最后一位制空
       所以删某个元素就是要从删除的元素开始往后全部拷贝一遍,然后制空最后一位如果数组数量多了效率就很低
       所以数组的读取效率高,删减效率低
        */
       /*将数组最后一位置空*/
       //所以数组的拷贝本质上就是数组的拷贝
       s1[s1.length - 1] = null;

       /*遍历打印数组内容*/
       for (int i = 0; i <= s1.length; i++){
           System.out.println(i + "--" + s1[i]);
      }
       /*
       会输出两次ee
       因为数组长度是5
        */
  }

   /*封装一个方法将上面的内容表示出来*/
   //处理字符串数组
   /*
   定义形参、返回值---参数化过程
    */
   public static String[] removeElement(String[] s, int index){

//       String[] s1 = {"aa","bb","cc","dd","ee"};
//       String[] s2 = new String[5];
       System.arraycopy(s,index + 1,s,index,s.length - index - 1);
       s[s.length - 1] = null;

       /*遍历打印数组内容*/
       for (int i = 0; i < s.length; i++){
           System.out.println(i + "--" + s[i]);
      }
       return s; //这样就实现了方法的封装---提取抽象化参数
  }

}

插入元素的方法---数组扩容、数组复制

    /*数组的插入、扩容*/
   //数组的扩容本质上是先定义一个更大的数组然后将原数组原封不动的拷贝到新数组中
   //封装这个方法
   public static String[] extendRange(String[] s1){
//       String[] s1 = {"aa","bb","cc"}; //因为数组只能实例化一次,后面不能变了

       /*定义更大的数组,new给数组划更大的区域*/
       String[] s2 = new String[s1.length * 2];

       /*将s1的所有元素拷贝到s2中*/
       System.arraycopy(s1,0,s2,0, s1.length);

       /*打印处s2的内容*/
       //正向for循环
       for (String temp : s2){
           System.out.println(temp);
      }
       return s2;
  }
}
public class TestArrayCopy {
   public static void main(String[] args) {
//       testBasicCopy2();

       /*定义一个数组,调用封装的方法*/
       String[] str = {"Alibaba","Bytedance","Tencent","Baidu"};

       /*调用removeElement删除元素*/
       removeElement(str,3);

       /*调用方法---直接调用*/
       str = extendRange(str);
  }
   //这个str发生了改变

复制、插入方法图解

 

It's a lonely road!!!
原文地址:https://www.cnblogs.com/JunkingBoy/p/14678583.html