Java基础 数组的知识点

数组
  1. 数组的定义:数组的本质是由java程序向虚拟机申请一串 连续的内存
    示意图
    Java基础 数组的知识点_第1张图片
  2. 数组的初始化可以有几种形式
    1 直接赋值(静态初始化)
    Object[] obj1 ={new Object(),new String("asd") ,new LinkedList()};
    
    2 初始化长度(动态初始化)
    		Object[] obj =new Object[10];
    
    可以初始化数组的长度,也可以在初始化数组时赋值, 一般数组初始化时,数字为0,对象为null
  3. 数组越界
    数组越界属于运行时异常,当数组访问长度超过数组本身长度时,就会抛出数组越界异常 java.lang.ArrayIndexOutOfBoundsException
  4. 数组指向和传递
    引用传递的本质是栈内存中的**字段(集合)**指向堆内存中的数据。当发生数组的赋值或者数组的函数参数传递时,传递的是值得引用,也就是将指向该数据的指针传递,使得指向同一块数据内存,从而达到数组传递的目的。所以,当堆内存的数据时,其他指向该数据段的引用都会被修改。
    Java基础 数组的知识点_第2张图片
  5. 二维数组
    二维数据是指在内存中定义一段连续的n m长度的内存,并且在java程序中可以理解为nm的表格。
  6. 数组的遍历
    for遍历
    
    for(int i = 0; i< 100 ;i++ )
    {
    	System.out.println(arr[i]);
    }
    
    foreach遍历
    for(Intager i : arr)
    {
    	System.out.println(i);
    }
    
操作数组的工具类:Arrays
  1. 额外方法:System.arraycopy():array的复制。
    int[] i = {0,1,2,3,4,5,6,7,8,9};
    int[] j ={10,11,22,33,44,55,66,77,88,99};
    //参数:被copy的数组,起始位置,copy的数组,起始位置,copy长度
    System.arraycopy(i,3,j,4,6);
    for (int k = 0; k < 10; k++) {
        System.out.print(i[k]);
    }
    System.out.println();
    for (int l = 0; l < 10; l++) {
        System.out.print(j[l]);
    }
    
    输出
    0   1   2   3   4   5   6   7   8   9   
    10   11   22   33   3   4   5   6   7   8   
    
  2. Arrays的asList()方法,返回值时一个list接口(必须强转成实现类才能接收)
    //底层新建了一个ArraysList,并返回一个list接口
    //以下语句会发生运行时错误,因为不能强转
    ArrayList als =(ArrayList)Arrays.asList(i);
    
  3. Arrays的Arrays.binarySearch()方法,二分查找,返回一个int下标
    //第一种方式(两个参数):查询的数组arr,查找的值(int,double,float等)
    //第二种方式(两个参数):查询的数组arr,查找的值(int,double,float等),对比函数comparator
    //第三种方式(四个参数):查询的数组arr,起始点int,结束点int,查找的值(int,double,float等)
    Arrays.binarySearch();
    
  4. Arrays的Arrays.copyOf()方法,复制数组,类似方法1,返回一个arr
    底层是通过传入的对象新建一个数组,然后通过System.out.arraycopy()方法来复制数组
    如果新数组的长度超过原数组的长度,则保留数组默认值
    //参数:被复制的数组arr,起始点int
    Arrays.copyOf(arr[],int );
    
    //参数:被复制的数组arr,起始点int,结束点
    Arrays.copyOfRange(arr[],int,int);
    
  5. Arrays的Arrays.equals()方法,返回一个boolean
    源码
    public static boolean equals(long[] a, long[] a2) {
        if (a==a2)
            return true;
        if (a==null || a2==null)
            return false;
    	//判断长度
        int length = a.length;
        if (a2.length != length)
            return false;
    	//对比数据
        for (int i=0; i<length; i++)
            if (a[i] != a2[i])
                return false;
    
        return true;
    }
    
    应用
    Arrays.equals();
    
  6. Arrays的 deepEquals(Object[] a1, Object[] a2)方法,返回一个boolean
    源码分析:
    public static boolean deepEquals(Object[] a1, Object[] a2) {
    	//判断地址是否相同
        if (a1 == a2)
            return true;
        //判断是否为null
        if (a1 == null || a2==null)
            return false;
        //判断长度是否相等
        int length = a1.length;
        if (a2.length != length)
            return false;
    	//如果数组对象相等则返回true,否则为false
        for (int i = 0; i < length; i++) {
            Object e1 = a1[i];
            Object e2 = a2[i];
    
            if (e1 == e2)
                continue;
            if (e1 == null)
                return false;
    		//调用deepEquals0(Object e1, Object e2)方法
            // Figure out whether the two elements are equal
            boolean eq = deepEquals0(e1, e2);
    
            if (!eq)
                return false;
        }
        return true;
    }
    
    Arrays的 deepEquals0(Object e1, Object e2)方法,放回一个boolean
    源码分析
    static boolean deepEquals0(Object e1, Object e2) {
        assert e1 != null;
        boolean eq;
        //如果传入参数是以下几种数组,则调用 deepEquals(Object[] a1, Object[] a2)方法,否则通过传入参数的equal方法对比。
        if (e1 instanceof Object[] && e2 instanceof Object[])
            eq = deepEquals ((Object[]) e1, (Object[]) e2);
        else if (e1 instanceof byte[] && e2 instanceof byte[])
            eq = equals((byte[]) e1, (byte[]) e2);
        else if (e1 instanceof short[] && e2 instanceof short[])
            eq = equals((short[]) e1, (short[]) e2);
        else if (e1 instanceof int[] && e2 instanceof int[])
            eq = equals((int[]) e1, (int[]) e2);
        else if (e1 instanceof long[] && e2 instanceof long[])
            eq = equals((long[]) e1, (long[]) e2);
        else if (e1 instanceof char[] && e2 instanceof char[])
            eq = equals((char[]) e1, (char[]) e2);
        else if (e1 instanceof float[] && e2 instanceof float[])
            eq = equals((float[]) e1, (float[]) e2);
        else if (e1 instanceof double[] && e2 instanceof double[])
            eq = equals((double[]) e1, (double[]) e2);
        else if (e1 instanceof boolean[] && e2 instanceof boolean[])
            eq = equals((boolean[]) e1, (boolean[]) e2);
        else
            eq = e1.equals(e2);
        return eq;
    }
    
    应用
    //参数为两个对象数组,而不能是基本类型,如果对象里有数组,则递归调用。底层通过对象的equal()方法对比
    Arrays.deepEquals(Object[],Object[]);
    
  7. Arrays的Arrays.deepHashCode();
    //通过该方法获取数组的hashcode,底层是Arrays自己的hashcode()方法
    Arrays.deepHashCode();
    
  8. Arrays的Arrays.fill()方法,让数组填充传入的参数
    //底层是遍历数组然后为每个下标赋值
    Arrays.fill(arr,int);
    
  9. Arrays的Arrays.sort()方法以及parallelSort此链接sort描述详细
    //第一种:直接排序 :arr
    //第二种:部分排序	:arr,int,int
    Arrays.sort()
    //并行排序,稳定排序,当超过一定阈值时分多线程进行多段归并排序
    Arrays.parallelSort();
    
  10. Arrays.parallelPrefix()方法
    调用ArrayPrefixHelpers.CumulateTask<>
    //通过传入参数对数组进行自定义操作(笔者的理解,可能不对)
    //参数:arr,function
    Arrays.parallelPrefix();
    
  11. Arrays.setAll()方法以及parallelSetAll方法
    //通过传入一个arr以及一个实现了IntFunction接口的方法,来实现对数组的初始化操作
    //与fill不同
    Arrays.setall(arr,function);
    //底层通过stream流的方式实现并行
    Arrays.parallelSetAll();
    //
    
  12. Arrays.stream();返回一个数组的流,可以对其进行流操作
  13. Arrays.spliterator();迭代器解析
数组变成List
  1. Arrays.asList();返回一个list接口,但数组转变成list,会变成一个存储数组的链表,很low对吧
  2. 通过初始化list,遍历数组加入
    List<String> resultList = new ArrayList<>(array.length);
    for (String s : array) {
        resultList.add(s);
    }
    
  3. 通过Collections的add方法,注意泛型操作
    List<String> resultList = new ArrayList<>(array.length);
    Collections.addAll(resultList,array);
    
  4. jdk9的list接口的List.of(array)方法
    List<String> resultList = List.of(array);
    
自定义数组学习(笔者很菜的,所以自己写的代码也很菜不需要看)
  1. 要求
    实现一个支持动态扩容的数组
    实现一个大小固定的有序数组,支持动态增删改操作
    实现两个有序数组合并为一个有序数组
    	public class MyArray<E> {
    
        protected Object[] arr;
    
        protected int DEFAULT_CAPACITY = 10;
    
        protected int size = 0;
    
        public MyArray(){
            this.arr = new Object[DEFAULT_CAPACITY];
        }
    
        public MyArray(int length){
            if(length < 0 ) {throw new IllegalArgumentException("Illegal Capacity: "+ length);}
            this.arr = new Object[length];
        }
    
        public boolean add(Object obj){
            if(obj == null)
            {
                return false;
            }
            check(size+1);
            arr[size]=obj;
            this.size++;
            return true;
        }
        public int delete(int index){
            if(index - size >0){throw new IllegalArgumentException("Illegal Capacity: ");}
            int number =(int)arr[index];
            System.arraycopy(arr, index+1 ,arr ,index ,(size - index - 1));
            arr[arr.length-1]=null;
            size--;
            return number;
        }
        public E get(int index){
            if(size-index >0)
            {
                return (E)arr[index];
            }else {
                throw new IndexOutOfBoundsException();
            }
        }
        private void check(int size){
            if(size - arr.length > 0)
            {
                int newSize = arr.length+arr.length>>1;
                arr = Arrays.copyOf(arr,newSize);
            }
        }
        public void show(){
            for (int i = 0; i < this.size; i++) {
                System.out.println(arr[i]);
            }
        }
    
        /**
         * 从小到大排序,归并排序
         * @param obj1
         * @param obj2
         * @return
         */
        public static MyArray sortAll(MyArray obj1 ,MyArray obj2){
            MyArray obj = new MyArray(obj1.size+obj2.size);
            int obj1index = 0;
            int obj2index = 0;
            int number1 = -1;
            int number2 = -1;
            while(obj.size != obj1.size+obj2.size)
            {
                //获取下标对应的数字并下表加1
                if(obj1index < obj1.size && number1 == -1){
                    number1 = (int)obj1.get(obj1index++);
                }
                if(obj2index < obj2.size && number2 == -1){
                    number2 = (int)obj2.get(obj2index++);
                }
                //
                if(number1 != -1 && number2 != -1)
                {
                    if(number1 < number2) {
                        obj.add(number1);
                        number1 = -1;
                    }else{
                        obj.add(number2);
                        number2 = -1;
                    }
                }else{
                    if(number1 == -1){
                        obj.add(number2);
                        number2 = -1;
                    }else{
                        obj.add(number1);
                        number1 = -1;
                    }
                }
            }
            return obj;
        }
    }
    

你可能感兴趣的:(java基础,数据结构)