数组特性,多维数据,java工具类Arrays

数组

本文是学习笔记,参考资料为:
极客时间:链接
王争老师github:地址
菜鸟教程:添加链接描述

定义

数据(Array)是一种线性表数据结构,它用一组连续的内存空间,来存储一组具有相同类型的数据。

线性表:数据排列地像一条线的数据结构,线性表上的数据只有前和后两个方向。常见的线性表结构有链表,队列,栈

非线性表:数据不像一条线进行排列,就是数据之间不只有简单的前后的关系。比如二叉树,堆和图

连续的内存空间:数据在物理存储上是放在一起的,占据的位置是连续的一片。

相同类型:每个内存单元存储的东西是一个类型的。

在这里插入图片描述

特性

1、支持随机访问,其实一个数据的访问本质上就是要找到该数据的内存地址,因为知道元素的是放在一块的,所以说对于数组中的数据有以下寻址方式。

a[i]_address = base_address + i * data_type_size

2、删除和插入的操作比较低效,因为删除和插入之后,为了保持内存空间连续的特性,需要进行元素的移动。

最好情况:插入和删除的位置在数组末尾,此时时间复杂度为O(1)

最坏情况:插入和删除的位置在数组头部,此时时间复杂度为O(n)

平均情况:(1+2+3+…+n)/n = O(n)

注意点

  1. 数组的特性是支持随机访问,并不是支持随机查找,依据下标进行随机访问的时间复杂度为O(1),查找的时间复杂度是不确定的,排好序的数据的复杂度为log n ;
  2. 插入时,如果不需要保持原有的相对顺序的话,那么可以直接将插入的元素放在末尾,然后跟需要插入的位置的现有元素交换位置就行;
  3. 数组越界的问题,对于C语言这种需要自己指定内存的语言,警防数组越界造成的问题;

Java中的数组实现

1、一维数组

创建方式1:new

dataType[] arrayRefVar = new dataType[arraySize];

上面这行代码做了两件事儿,第一件是声明了arrayRefVar是一个dataType类型的数组,第二件是创建了一个arraySize大小的数组

创建方式2:直接赋值

dataType[] arrayRefVar = {value0, value1, ..., valuek};

创建方式3:前两者综合

dataType[] arrayRefVar = new dataType[arraySize]{value0,
 value1, ..., valuek};

参考菜鸟教程的例子:Java 数组 | 菜鸟教程 (runoob.com)

public class TestArray {
   public static void main(String[] args) {
      // 数组大小
      int size = 10;
      // 定义数组
      double[] myList = new double[size];
      myList[0] = 5.6;
      myList[1] = 4.5;
      myList[2] = 3.3;
      myList[3] = 13.2;
      myList[4] = 4.0;
      myList[5] = 34.33;
      myList[6] = 34.0;
      myList[7] = 45.45;
      myList[8] = 99.993;
      myList[9] = 11123;
      }
  }

在这里插入图片描述

2、多维数组(以二维数组为例)

多维数组可以看作是元素为数组的数组;

创建方式1:new

type[][] typeName = new type[typeLength1][typeLength2];

这种方式直接为每一维分配好了空间大小,type的类型可以是基本数据类型,也可以是引用数据类型

创建方式2:从最高维开始,分别为每一维分配空间

String[][] s = new String[2][];
s[0] = new String[2];
s[1] = new String[3];
s[0][0] = new String("Good");
s[0][1] = new String("Luck");
s[1][0] = new String("to");
s[1][1] = new String("you");
s[1][2] = new String("!");

3、 数组的工具类 Arrays

方法1:填充数组 fill

不指定范围的时候,就是全部填充了。

public static void fill(int[] a,
                        int fromIndex,
                        int toIndex,
                        int val)

方法2: 比较相等 equals

public static boolean equals(Object[] a,
                             Object[] a2)

如果两个指定的 Objects 数组彼此相等,则返回 true。如果两个数组包含相同数量的元素,并且两个数组中的所有相应元素对都是相等的,则认为这两个数组是相等的。如果 (e1null ? e2null : e1.equals(e2)),则认为 e1 和 e2 这两个对象是相等的 。换句话说,如果两个数组以相同顺序包含相同的元素,则两个数组是相等的。此外,如果两个数组引用都为 null,则认为它们是相等的

方法3:升序排序 sort

public static <T> void sort(T[] a,
                            int fromIndex,
                            int toIndex,
                            Comparator<? super T> c)
    参数:
a - 要排序的数组
fromIndex - 要排序的第一个元素的索引(包括)
toIndex - 要排序的最后一个元素的索引(不包括)
c - 确定数组顺序的比较器。null 值指示应该使用元素的自然顺序。

根据指定比较器产生的顺序对指定对象数组的指定范围进行排序。排序的范围从索引 fromIndex(包括)一直到索引 toIndex(不包括)。(如果 fromIndex==toIndex,则排序范围为空。)此范围内的所有元素都必须是通过指定比较器可相互比较的;

注意这种排序方法,对于基本的数据类型,排序的结果是升序,如果需要降序的话,只能自行进行数组的倒置(双指针法)

对于引用数据类型,可以按照自己定义的顺序来进行排列。

基本数组类型
public static void main(String[] args) {
    int[] array = new int[]{1, 21, 3, 44, 5, 18};
    System.out.print("排序前: ");
    System.out.println(Arrays.toString(array));
    Arrays.sort(array);
    System.out.print("排序后: ");
    System.out.println(Arrays.toString(array));
}

// 排序前: [1, 21, 3, 44, 5, 18]
// 排序后: [1, 3, 5, 18, 21, 44]
引用数据类型
package Array;
import java.util.Arrays;

public class SelfArray {

    class Student {
        int age;
        String name;

        Student(String _name, int _age) {
            this.age = _age;
            this.name = _name;
        }

        @Override
        public String toString() {
            return "[age=" + age + ", name=" + name + "]";
        }
    }
    
    public static void main(String[] args) {
        Student[] stu = new Student[4];
        stu[0] = new SelfArray().new Student("dog", 4);
        stu[1] = new SelfArray().new Student("cat", 15);
        stu[2] = new SelfArray().new Student("fish", 2);
        stu[3] = new SelfArray().new Student("wolf", 14);
        System.out.println("排序前: ");
        for (Student student : stu) {
            System.out.println(student.toString());
        }
        
// 经典写法
//        Arrays.sort(stu, new Comparator<Student>() {
//            @Override
//            public int compare(Student s1, Student s2) {
//                return s1.age - s2.age;    // 从小到大排序,相减为负的在前面的
//            }
//        });
        
        // lamda表达式的写法,升序
        Arrays.sort(stu, ((o1, o2) -> o1.age - o2.age));  
        System.out.println("排序后: ");
        for (Student student : stu) {
            System.out.println(student.toString());
        }
    }
}
/**
排序前: 
[age=4, name=dog]
[age=15, name=cat]
[age=2, name=fish]
[age=14, name=wolf]
排序后: 
[age=2, name=fish]
[age=4, name=dog]
[age=14, name=wolf]
[age=15, name=cat]
**/

手动实现

package Array;
/**
 * 数组的插入,删除,以及按照下标的访问
 */
public class Array {
    public int[] data;
    // 数组容量的大小
    private int n;
    // 当前的数组实际长度,用来判断插入以及删除是否合法等
    private int count;

    public Array(int n) {
        this.n = n;
        this.data = new int[n];
        this.count = 0;
    }

    public Array() {
    }

    //插入元素:头部插入,尾部插入
    public boolean insert(int value) {
        if (count == n) {
            System.out.println("数组空间已满!");
            return false;
        }
        data[count] = value;
        count++;
        return true;
    }

    public boolean insert(int index, int value) {
        if (index < 0 || index >= n) {
            System.out.println("插入位置不合法");
            return false;
        }
        if (count == n) {
            System.out.println("数组空间已满");
            return false;
        }
        for (int j = count; j > index; j--) {
            data[j] = data[j - 1];  // 向后移位
        }
        data[index] = value;
        count++;
        return true;
    }

    //根据索引,找到数据中的元素并返回
    public int find(int index) {
        if (index < 0 || index >= n) {
            System.out.println("索引位置有误");
            return -1;
        }
        return data[index];
    }

    //根据索引,删除数组中元素
    public boolean delete() {
        if (count == 0) {
            System.out.println("数组为空!");
            return false;
        }
        count--;
        return true;
    }

    public boolean delete(int index) {
        if (count == 0) {
            System.out.println("数组为空");
            return false;
        }
        if (index < 0 || index >= n) {
            System.out.println("索引不合法!");
            return false;
        }
        for (int i = index + 1; i < count; i++) {
            data[i - 1] = data[i];   // 向前移位
        }
        count--;
        return true;
    }

    public void printAll() {
        for (int i = 0; i < count; i++) {
            System.out.print(data[i] + " ");
        }
    }

    public static void main(String[] args) {
        Array test = new Array(10);
        test.insert(5);
        test.insert(51);
        test.insert(15);
        test.insert(125);
        test.insert(12555);
        test.printAll();
    }
}
    //  5 51 15 125 12555 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值