【数据结构、java学习】数组(Array)

1,概念

  1. 数组一旦定义,其维数和维界就不再改变。
    因此除了结构的初始化和销毁之外,数组只有存取元素和修改元素值的操作。
  2. Array可以存放对象类型、基本数据类型的数据。
  3. 数组中元素在内存中按顺序线性存放,通过第一个元素就能访问随后的元素,这样的数组称之为"真数组"。

1)java中定义

java 复制代码
//一维数组的定义:在内存中开辟一块连续的存储空间,大小是 6 * sizeof(float)= 36*4 字节
//二维数组的定义:行连续,每行对应一个一维数组,但是每一行之间不连续。
float f[][] = new float[6][6];
float []f[] = new float[6][6];
float [][]f = new float[6][6];
float [][]f = new float[6][];

//赋值:计算a的首地址,计算a[1]偏移量,找到a[1]地址,写入数据2
a[1] = 2;

2)java中复制数组

当数据量很大时,复制的效率:
System.arraycopy > clone() > Arrays.copyOf> for循环

以上均为浅拷贝;要实现深拷贝,需要在 clone() 方法中手动创建并初始化所有引用类型的属性,此时要考虑避免循环引用(无限递归导致OOM)、破坏类的封装性。

浅拷贝(Shallow Clone,对应深拷贝):

引用的对象只会拷贝引用地址,而不会将引用的对象重新分配内存

1>System.arraycopy

System类源码中给出了arraycopy的方法,是native方法,也就是本地方法,肯定是最快的。

java 复制代码
//数据量小的时候,for可能快。
public static void arraycopy(Object src,  //源数组
                             int srcPos,  //源数组中的起始位置
                             Object dest, //目标数组
                             int destPos, //目标数据中的起始位置
                             int length)  //要复制的数组元素的数量
                             
System.arraycopy(a1, 2, a2, 3, 2);

2>clone()

java.lang.Object类的clone()方法为protected类型,不可直接调用,需要先对要克隆的类进行下列操作:

  1. 被克隆的类实现Cloneable接口;
  2. 被克隆的类覆盖clone()方法,并且在该clone()方法中调用super.clone();
java 复制代码
    //1. 被克隆的类要实现Cloneable接口
    class Cat implements Cloneable {
        private String name;
        private int age;

        public Cat(String name, int age) {
            this.name = name;
            this.age = age;
        }

        //2. 重写clone()方法
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
  1. 调用
java 复制代码
            //调用clone方法
            Cat cat2 = (Cat) cat1.clone();

3>Arrays.copyOf()、 copyOfRange()

Arrays.copyOf有十种重载方法,复制指定的数组,返回原数组的副本。
copyOf() 方法是复制数组至指定长度的(新)数组;
copyOfRange() 方法则将指定数组的指定长度复制到一个新数组中。

java 复制代码
//newLength大于原数组,会用desc的元素填充,默认为null
T[] copyOf(T[] original, int newLength) 
//endIndex大于原数组,会用desc的元素填充,默认为null
Arrays.copyOfRange(dataType[] srcArray,int startIndex,int endIndex)

4>for循环

直接for循环效率最高,其次是迭代器和 ForEach操作。

3)数组排序

java 复制代码
//asc排序
Arrays.sort(nums)
Arrays.sort(int[] a, int fromIndex, int toIndex)

//用Comparator接口实现自定义排序规则
Arrays.sort(T[] a, Comparator<? Super T> c)
//举例:降序
Arrays.sort(arr, new Comparator<Integer>() {
    //重写compare方法,最好加注解,不加也没事
    public int compare(Integer a, Integer b) {
        //返回值>0交换
           return b-a;
     }
});

2,应用

1)哈希表

把数组的下标设为哈希表的键值(key),而把数组中每一个数字设为哈希表的值(value),有了这样的哈希表,就可以O(1)实现查找。从而快速高效的解决很多问题。

相关推荐
董董灿是个攻城狮1 天前
AI视觉连载8:传统 CV 之边缘检测
算法
怒放吧德德1 天前
Netty 4.2 入门指南:从概念到第一个程序
java·后端·netty
雨中飘荡的记忆1 天前
大流量下库存扣减的数据库瓶颈:Redis分片缓存解决方案
java·redis·后端
心之语歌1 天前
基于注解+拦截器的API动态路由实现方案
java·后端
华仔啊1 天前
Stream 代码越写越难看?JDFrame 让 Java 逻辑回归优雅
java·后端
ray_liang1 天前
用六边形架构与整洁架构对比是伪命题?
java·架构
AI软著研究员1 天前
程序员必看:软著不是“面子工程”,是代码的“法律保险”
算法
FunnySaltyFish1 天前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
Ray Liang1 天前
用六边形架构与整洁架构对比是伪命题?
java·python·c#·架构设计
颜酱1 天前
理解二叉树最近公共祖先(LCA):从基础到变种解析
javascript·后端·算法