草庐IT

Java 浅谈数组(Array)和列表(ArrayList)的区别 介绍Arrays常用方法

senxu_ 2023-04-08 原文

目录

一.数组和列表的区别

1.数组(Array)

(1)数组(Array)

(2)数组的声明与创建

(3)多维数组

(4)数组的优缺点

2.列表(ArrayList)

(1)列表(ArrayList)

(2)列表的声明与创建

(3)列表的优缺点

3.数组(Array)与列表(ArrayList)的区别

(1)空间大小

(2)存储内容

(3)删除方法

二.Arrays类常用方法

1.赋值

fill()

2.排序

sort()

3.查找

binarySearch()

4.比较

equals()

5.复制

copyOf()

copyOfRange()


java.util.Arrays类是一个操作数组的工具类,包含各种操作数组的方法,允许将数组视为列表

一.数组和列表的区别

1.数组(Array)

(1)数组(Array)

        Java语言中提供的数组是用来存储固定大小的同类型元素。

  • 数组是数据结构中的一种线性数据结构。
  • 数组可以说是一个容器或者是一个集合。
  • 在数组中只能存储同一类型的数据,在定义数组的时候必须要指定数据类型。
  • 如果数组中要添加不同的数据类型,只需把数组的类型定义为Object。
  • 数组能存储的元素个数是固定的,因为数组在定义的时候必须要指定长度。
  • Java中数组是类,它只有唯一一个属性length(数组的长度)。
  • length属性的计算值是从1开始计算的,而数组的下标,是从0开始计算的。

(2)数组的声明与创建

        首先必须声明数组变量,才能在程序中使用数组。

dataType[] arrayRefVar;  (首选)        或       dataType arrayRefVar[];                

        Java使用new操作符来创建数组。

arrayRefVar = new dataType[arraySize]; 

        我们也可以将声明和创建用一条语句完成:

dataType[] arrayRefVar = new dataType[arraySize];

         我们也可以这样来创建数组:

dataType[] arrayRefVar = {value0,value1,value2,value3,value4,value5};

(3)多维数组

        Java 中没有多维数组的概念,从数组底层的运行机制上来看 Java 没有多维数组,但是 Java 提供了支持多维数组的语法,可以实现多维数组的功能。

        Java 语言里的数组类型是引用类型,因此数组变量其实是一个引用,这个引用指向真实的数组内存。数组元素的类型也可以是引用,如果数组元素的引用再次指向真实的数组内存,这种情形看上去很像多维数组。

       所以, 多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。

多维数组的动态初始化(以二维为例)

type[][] typeName = new type[typeLength1][typeLength2];   (首选)

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

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

(typeLength1是行数,typeLength2是列数 )

由于多维数组可以看成是数组的数组,我们同样可以分别为每一维分配引用空间

String[][] str = new String;

str[0] = new String[2];           //该二维数组有2行

str[1] = new String[2];           //该二维数组有2列

多维数组的引用 (以二维为例)

对二维数组中的每个元素,引用方式为arrayName[index1][index2],index1为行索引,index2为列索引

str[1][0];           //第二行第一列

(4)数组的优缺点

优点:数组是所有数据结构中存储和获取速度最快的一种。

缺点:数组的长度是固定的,如果要删除或添加数据会不方便,删除的时候空间会浪费,添加的时候如果数据已经加满了,就无法添加新的数据。

2.列表(ArrayList)

本文的列表主要用于和数组做对比,ArrayList的实现基于数组,LinkedList的实现基于双向链表,故本文主要介绍ArrayList

(1)列表(ArrayList)

ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。

(2)列表的声明与创建

ArrayList 类位于 java.util 包中,使用前需要引入它

import java.util.ArrayList;

 

ArrayList<E> objectName = new ArrayList<>();      

//E:泛型数据类型,只能为引用数据类型

(3)列表的优缺点

优点:

  • 支持自动改变大小
  • 可以灵活的插入元素
  • 可以灵活的删除元素

缺点:牺牲效率,比一般的数组慢

3.数组(Array)与列表(ArrayList)的区别

列表(ArrayList)是对数组(Array)的一个加强

(1)空间大小

  • Array的空间大小是固定的,空间不够时也不能再次申请,所以需要事前确定合适的空间大小。
  • ArrayList的空间是动态增长的,如果空间不够,它会创建一个空间比原空间大0.5倍的新数组,然后将所有元素复制到新数组中,接着抛弃旧数组。而且,每次添加新的元素的时候都会检查内部数组的空间是否足够。

(2)存储内容

  • Array数组可以包含基本类型和对象类型。
  • ArrayList却只能包含对象类型。

(3)删除方法

  • Array数组没有提供删除方法
  • ArrayList中有remove()方法

建议:基于效率和类型检验,应尽可能使用Array, 无法确定数组大小时使用ArrayList,
解决一般化的问题时,建议使用ArrayList。

二.Arrays类常用方法

Arrays类里的方法均被static修饰(即为静态方法),故可以直接通过Arrays.xxx(xxx)的形式调用方法,下面介绍Arrays类的一些常用方法,常用方法大致可以分为:赋值,排序,查找,比较,复制

1.赋值

fill()

将指定的值分配给指定数组指定范围中的每个元素。

public static void fill(arrayname,value)

public static void fill(arrayname ,starting index ,ending index ,value)

import java.util.*;
public class Example{
    public static void main(String[] args) {
        int array[] = new int[10];
        Arrays.fill(array, 1);
        for (int arrays:array) {
            System.out.print(arrays+" ");
        }
        System.out.println();
        Arrays.fill(array, 3, 6, 9);
        for (int arrays:array) {
            System.out.print(arrays+" ");
        }
    }
}
1 1 1 1 1 1 1 1 1 1 
1 1 1 9 9 9 1 1 1 1 

2.排序

sort()

对指定对象数组根据其元素的自然顺序进行升序排列。

public static void sort(Object[] arrayname)     

//对一个数组的所有元素进行排序,并且是按从小到大的顺序

public static void sort(Object[] arrayname,int fromIndex, int toIndex)

//对数组部分排序,也就是对数组a的下标从fromIndex到toIndex-1的元素排序

import java.util.*;
public class Example{
    public static void main(String[] args) {
        int array[] = {2,5,85,30,75,66,-18,0};
        Arrays.sort(array,2,5);
        for (int arrays:array) {
            System.out.print(arrays+" ");
        }
        System.out.println();
        Arrays.sort(array);
        for (int arrays:array) {
            System.out.print(arrays+" ");
        }
    }
}
2 5 30 75 85 66 -18 0 
-18 0 2 5 30 66 75 85 

Arrays.sort()的底层原理:

假设数组长度为n

  • 1<=n<47,使用插入排序
  • 47<=n<286,使用快速排序
  • n>=286,使用归并排序或快速排序(有一定顺序使用归并排序,毫无顺序使用快速排序)

这里简单了解即可,关于各种排序的算法原理和复现,后续在讲算法的时候会单独发一篇博客来说明的

3.查找

binarySearch()

用二分查找算法在给定数组中搜索给定值的对象。

数组在调用前必须排序好的。

public static int binarySearch(Object[] a,Object key)

//在一个数组的所有元素中进行查找

返回值:

  • 在数组范围内,索引值为“ - 插入点索引值”
  • 小于数组内元素,索引值为 – 1
  • 大于数组内元素,索引值为 – (length + 1)

public static int binarySearch(Object[] a,int fromIndex,int toIndex,Object key)

//在该数组指定的范围内进行查找

返回值:

  • 在搜索范围内,索引值为“ - 插入点索引值”
  • 小于搜索范围内元素,返回–(fromIndex + 1)
  • 大于搜索范围内元素,返回 –(toIndex + 1)
import java.util.*;
public class Example{
    public static void main(String[] args) {
        int array[] = {2,5,85,30,75,66,-18,0};
        Arrays.sort(array);
        for (int arrays:array) {
            System.out.print(arrays+" ");
        }
        System.out.println();
        System.out.println(Arrays.binarySearch(array,5));
        System.out.println(Arrays.binarySearch(array,-99));
        System.out.println(Arrays.binarySearch(array,100));
        System.out.println(Arrays.binarySearch(array,60));
        System.out.println(Arrays.binarySearch(array,1,5,5));
        System.out.println(Arrays.binarySearch(array,1,5,-99));
        System.out.println(Arrays.binarySearch(array,1,5,100));
        System.out.println(Arrays.binarySearch(array,1,5,60));
    }
}
-18 0 2 5 30 66 75 85 
3         //5在数组内,返回排完序后的索引3
-1        //-99小于数组内元素,返回索引值为-1
-9        //100大于数组内元素,返回索引值为-(length+1)=-(8+1)
-6        //60在数组范围内,返回索引值为-插入点索引值=-6
3         //5在搜索范围内,返回排完序后的索引3
-2        //-99小于搜索范围内元素,返回–(fromIndex + 1)=-(1+1)=-2
-6        //100大于搜索范围内元素,返回–(toIndex + 1)=-(5+1)=-6
-6        //60在搜索范围内,索引值为-插入点索引值=-6

二分查找算法原理和复现也会在之后的博客里提到

4.比较

equals()

如果两个指定的数组彼此相等,则返回 true。如果两个数组包含相同数量的元素,并且两个数组中的所有相应元素对都是相等的,则认为这两个数组是相等的。换句话说,如果两个数组以相同顺序包含相同的元素,则两个数组是相等的。

public static boolean equals(Object[] arrayname,Object[] arrayname2)

import java.util.*;
public class Example{
    public static void main(String[] args) {
        int[] array1 = {2,5,85,30,75,66,-18,0};
        int[] array2 = {75,2,66,30,5,85,0,-18};
        
        if(Arrays.equals(array1, array2)){
            System.out.println("array1等于array2");
        }
        else{
            System.out.println("array1不等于array2");
        }
        
        Arrays.sort(array1);
        Arrays.sort(array2);
        
        for(int arrays:array1){
            System.out.print(arrays+" ");
        }
        System.out.println();
        for(int arrays:array2){
            System.out.print(arrays+" ");
        }     
        System.out.println();
        
        if(Arrays.equals(array1, array2)){
            System.out.println("排序后,array1等于array2");
        }
        else{
            System.out.println("排序后,array1不等于array2");
        }
    }
}
array1不等于array2
-18 0 2 5 30 66 75 85 
-18 0 2 5 30 66 75 85 
排序后,array1等于array2

5.复制

copyOf()

将原始数组的元素,复制到新的数组中,可以设置复制的长度(即需要被复制的元素个数)

public static Object[] copyOf(original,newLength)

copyOfRange()

将某个范围内的元素复制到新的数组中

public static Object[] copyOfRange(original,int from,int to)

//from为拷贝的开始位置(包含),to为拷贝的结束位置(不包含)

import java.util.*;
public class Example{
    public static void main(String[] args) {
        int[] array1 = {2,5,85,30,75,66,-18,0};
        int[] array2 = Arrays.copyOf(array1, 6);
        int[] array3 = Arrays.copyOfRange(array1, 2, 4);
        System.out.println(Arrays.toString(array1));
        System.out.println(Arrays.toString(array2));
        System.out.println(Arrays.toString(array3));       
    }
}
[2, 5, 85, 30, 75, 66, -18, 0]
[2, 5, 85, 30, 75, 66]
[85, 30]

有关Java 浅谈数组(Array)和列表(ArrayList)的区别 介绍Arrays常用方法的更多相关文章

  1. ruby - 在 Ruby 中实现 `call_user_func_array` - 2

    我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)

  2. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  3. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  4. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  5. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  6. Ruby Koans about_array_assignment - 非平行与平行分配歧视 - 2

    通过ruby​​koans.com,我在about_array_assignment.rb中遇到了这两段代码你怎么知道第一个是非并行赋值,第二个是一个变量的并行赋值?在我看来,除了命名差异之外,代码几乎完全相同。4deftest_non_parallel_assignment5names=["John","Smith"]6assert_equal["John","Smith"],names7end45deftest_parallel_assignment_with_one_variable46first_name,=["John","Smith"]47assert_equal'John

  7. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  8. ruby - RVM 使用列表[0] - 2

    是否有类似“RVMuse1”或“RVMuselist[0]”之类的内容而不是键入整个版本号。在任何时候,我们都会看到一个可能包含5个或更多ruby的列表,我们可以轻松地键入一个数字而不是X.X.X。这也有助于rvmgemset。 最佳答案 这在RVM2.0中是可能的=>https://docs.google.com/document/d/1xW9GeEpLOWPcddDg_hOPvK4oeLxJmU3Q5FiCNT7nTAc/edit?usp=sharing-知道链接的任何人都可以发表评论

  9. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  10. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

随机推荐