精华内容
下载资源
问答
  • Java数组转List的三种方式及对比

    万次阅读 多人点赞 2018-03-18 00:10:04
    本文介绍Java数组转为List三种情况的优劣对比,以及应用场景的对比,以及程序员常犯的类型转换错误原因解析。

    前言:

    本文介绍Java中数组转为List三种情况的优劣对比,以及应用场景的对比,以及程序员常犯的类型转换错误原因解析。

    一.最常见方式(未必最佳)

    通过 Arrays.asList(strArray) 方式,将数组转换List后,不能对List增删,只能查改,否则抛异常。

    关键代码List list = Arrays.asList(strArray);

    private void testArrayCastToListError() {
    		String[] strArray = new String[2];
    		List list = Arrays.asList(strArray);
    		//对转换后的list插入一条数据
    		list.add("1");
    		System.out.println(list);
    	}
    

    执行结果

    Exception in thread "main" java.lang.UnsupportedOperationException
    	at java.util.AbstractList.add(AbstractList.java:148)
    	at java.util.AbstractList.add(AbstractList.java:108)
    	at com.darwin.junit.Calculator.testArrayCastToList(Calculator.java:19)
    	at com.darwin.junit.Calculator.main(Calculator.java:44)
    

    程序在list.add(“1”)处,抛出异常:UnsupportedOperationException。

    原因解析
    Arrays.asList(strArray)返回值是java.util.Arrays类中一个私有静态内部类java.util.Arrays.ArrayList,它并非java.util.ArrayList类。java.util.Arrays.ArrayList类具有 set(),get(),contains()等方法,但是不具有添加add()或删除remove()方法,所以调用add()方法会报错。

    使用场景Arrays.asList(strArray)方式仅能用在将数组转换为List后,不需要增删其中的值,仅作为数据源读取使用。

    二.数组转为List后,支持增删改查的方式

    通过ArrayList的构造器,将Arrays.asList(strArray)的返回值由java.util.Arrays.ArrayList转为java.util.ArrayList

    关键代码ArrayList<String> list = new ArrayList<String>(Arrays.asList(strArray)) ;

    private void testArrayCastToListRight() {
    		String[] strArray = new String[2];
    		ArrayList<String> list = new ArrayList<String>(Arrays.asList(strArray)) ;
    		list.add("1");
    		System.out.println(list);
    	}
    

    执行结果:成功追加一个元素“1”。

    [null, null, 1]
    

    使用场景:需要在将数组转换为List后,对List进行增删改查操作,在List的数据量不大的情况下,可以使用。

    三.通过集合工具类Collections.addAll()方法(最高效)

    通过Collections.addAll(arrayList, strArray)方式转换,根据数组的长度创建一个长度相同的List,然后通过Collections.addAll()方法,将数组中的元素转为二进制,然后添加到List中,这是最高效的方法。

    关键代码

    ArrayList< String> arrayList = new ArrayList<String>(strArray.length);
    Collections.addAll(arrayList, strArray);
    

    测试:

    private void testArrayCastToListEfficient(){
    		String[] strArray = new String[2];
    		ArrayList< String> arrayList = new ArrayList<String>(strArray.length);
    		Collections.addAll(arrayList, strArray);
    		arrayList.add("1");
    		System.out.println(arrayList);
    	}
    

    执行结果:同样成功追加一个元素“1”。

    [null, null, 1]
    

    使用场景:需要在将数组转换为List后,对List进行增删改查操作,在List的数据量巨大的情况下,优先使用,可以提高操作速度。

    注:附上Collections.addAll()方法源码:

    public static <T> boolean addAll(Collection<? super T> c, T... elements) {
            boolean result = false;
            for (T element : elements)
                result |= c.add(element);//result和c.add(element)按位或运算,然后赋值给result
            return result;
        }
    

    四.Java8可通过stream流将3种基本类型数组转为List

    如果JDK版本在1.8以上,可以使用流stream来将下列3种数组快速转为List,分别是int[]long[]double[],其他数据类型比如short[]byte[]char[],在JDK1.8中暂不支持。由于这只是一种常用方法的封装,不再纳入一种崭新的数组转List方式,暂时算是java流送给我们的常用工具方法吧。

    转换代码示例如下:

    List<Integer> intList= Arrays.stream(new int[] { 1, 2, 3, }).boxed().collect(Collectors.toList());
    List<Long> longList= Arrays.stream(new long[] { 1, 2, 3 }).boxed().collect(Collectors.toList());
    List<Double> doubleList= Arrays.stream(new double[] { 1, 2, 3 }).boxed().collect(Collectors.toList());
    

    如果是String数组,可以使用Stream流这样转换:

    String[] arrays = {"tom", "jack", "kate"};
    List<String> stringList= Stream.of(arrays).collect(Collectors.toList());
    

    --------------------------------------正文结束,以下是对评论中的问题集中回复和讲解--------------------------------------


    补充:回答评论中的疑问

    问题: 有评论提出:数组类型如果是整型数组,转为List时,会报错?

    答案:JDK1.8环境中测试,这三种转换方式是没有问题的。放心使用。对于Integer[]整型数组转List的方法和测试结果如下:

    1. 方式一:不支持增删
    Integer[] intArray1 = new Integer[2];
    List<Integer> list1 = Arrays.asList(intArray1);
    System.out.println(list1);
    

    运行结果:

    [null, null]
    
    1. 方式二:支持增删
    Integer[] intArray2 = new Integer[2];
    List<Integer> list2 = new ArrayList<Integer>(Arrays.asList(intArray2)) ;
    list2.add(2);
    System.out.println(list2);
    

    运行结果:

    [null, null, 2]
    
    1. 方式三:支持增删,且数据量大最高效
    Integer[] intArray3 = new Integer[2];
    List<Integer> list3 = new ArrayList<Integer>(intArray3.length);
    Collections.addAll(list3, intArray3);
    list3.add(3);
    System.out.println(list3);
    

    运行结果:

    [null, null, 3]
    

    综上,整型Integer[]数组转List<Integer>的正确方式应该是这样的。

    猜想你们遇到的问题: 由于评论没有给出报错的代码,所以我猜想你们出现的错误可能是这样转换的:

    int[] intArray1 = new int[2];
    List<Integer> list1 = Arrays.asList(intArray1);//此处报错!!!
    

    报错原因:等号两边类型不一致,当然编译不通过。分析见下文。

    那么在声明数组时,用int[] 还是Integer[],哪种声明方式才能正确的转为List呢?
    答案: 只能用Integer[]List<Integer>,即只能用基本数据类型的包装类型,才能直接转为List

    原因分析如下:

    我们来看List在Java源码中的定义(别害怕看不懂源码,看我分析,很易懂的):

    public interface List<E> extends Collection<E> {省略…}
    

    再来看Arrays.asList()的在Java源码定义:

     public static <T> List<T> asList(T... a) {
            return new ArrayList<>(a);
        }
    
    • 从上述源码中可以看出,List声明时,需要传递一个泛型<E>作为形参,asList()参数类型也是泛型中的通配类型<T>Java中所有的泛型必须是引用类型

    • 什么是引用类型?Integer是引用类型,那int是什么类型?int是基本数据类型,不是引用类型。这就是为什么java中没有List<int>,而只有List<Integer>

    • 举一反三:其他8种基本数据类型byte、short、int、long、float、double、char都不是引用类型,所以8种基本数据类型都不能作为List的形参。但String、数组、class、interface是引用类型,都可以作为List的形参,所以存在List<Runnable>接口类型的集合、List<int[]>数组类型的集合、List<String>类的集合。但不存在list<byte>list<short> 等基本类型的集合。

    有了上述基础知识后,再来看为什么下面两行代码第二行能编译通过,第三行却编译报错?

    int[] intArray1 = new int[1]; 
    Arrays.asList(intArray1);//编译不报错
    List<Integer> list1 = Arrays.asList( intArray1);//编译报错
    

    答案:

    • 第二行代码,Arrays.asList()方法的入参是个引用类型的int[],那么返回值类型一定是List<int[]> ,其完整代码是:List<int[]> intsArray = Arrays.asList(intArray1);,所以编译通过,没问题。
    • 第三行报错,因为等号两边的类型不一致,左边:List<Integer>,右边List<int[]>,所以编译时就报错。

    总结

    现在你应该明白,为什么int[]不能直接转换为List<Integer>,而Integer[]就可以转换为List<Integer>了吧。因为List中的泛型必须是引用类型,int是基本数据类型,不是引用类型,但int的包装类型Integerclass类型,属于引用类型,所以Integer可以作为List形参,List<Integer>在java中是可以存在的,但不存在List<int>类型。

    在编码时,我们不光要知其然,还要知其所以然,通过分析JDK源码,才能得出一手信息,不仅了解到了如何用,还能得出为何这样用。

    希望我的解答对你有帮助,有疑惑的地方,可以在文章下方评论,我会给大家解惑的,喜欢本文请点赞和收藏。

    展开全文
  • java数组的总结

    千次阅读 多人点赞 2016-08-22 16:03:38
    java数组定义的方法,java数组的简单使用,java数组相关类和方法的介绍,java数组编程题目的讲解

    Java数组的总结

    本文将对java数组做详细介绍:包括一维二维数组的定义,封装类Arrays和数组封装方法做一点介绍,

    最后介绍几道数组的编程题目的解法。

     

    一、数组的定义

    一维数组

    Java中有两种数据:primitive类型和objects.

    数组必须初始化后才可使用。

    数组属于object类型,所以必须用new来创建数组,同时数组具备一下特性:

    1. 数组创建之后就不能改变大小

    2. 数组创建之后,若没有指定初始值,则依据数组类型的不同,会预设不同的初始值

      数组初始化方式:

     1、静态初始化:Int[] arr1= new int[]{1,2,3,4,5};int[] arr1={1,2,3,4,5};

     2动态初始化:Int[] arr1=new int[5];  // 创建一个可容纳5个元素的数组 

    3. 数组有一个length属性,可以取回数组中元素的个数

    int arrayLength = arr1.length;

     

    二维数组

    二维数组用数组“名称”与“两个索引”来指定存取数组中的元素。

    其定义方式与一维数组类似:

     1、静态初始化:int[][] arr1= {{1,2,3}, {4,5,6}};

     2动态初始化:int[][] arr1=new int[3][3];

    注意length所代表的长度,数组名后直接加上length(如arr.length),所指的是数组有几行; 指定索引后加上length(如arr[0].length),指的是该行拥有的元素,也就是列的数目。

    值得注意的是,数组的游标是从0 开始的,比如一位数组的第一个元素:arr1[0]=1; arr[4]=5;

    二位数组中:arr2[0][0]=1;  arr2[2][2]=6;

     

    二、数组封装类和方法的使用

    数组的复制

    1. 使用System.arraycopy()方法,可以赋值一个数组的部分值到另一个数组

       System.arraycopy(来源,起始索引,目的,起始索引,复制长度);

       例如:

       int[]arr1 = {1,2,3,4,5};

       int[]arr2 = new int[5];

      System.arraycopy(arr1, 0, arr2, 0, arr1.length);//之后数组2的值等于数组1的值

    2. Java SE 6中,Arrays类新增了copyOf()方法,可以直接返回一个新的数组对象,而其中包括复制的内容

       例如:

       importjava.util.Arrays;

       int[]arr1 = {1,2,3,4,5};

       int[]arr2 = Arrays.copyOf(arr1,arr1.length);

       ArrayscopyOf()方法返回的数组是新的数组对象,所以改变返回数组中元素的值不会影响原来数组中元素的值。copyOf()方法中第二个变量指定新数组的长度,如果新数组的长度超过原来数组的长度,则多出来的元素会保留数组默认值。

       除了copyOf()方法外,还有copyOfRange()方法,可以指定来源数组以及要复制的索引范围:

       int arr1= {1,2,3,4,5};

       intarr2 = Array.copyOfRange(arr1,1,4);  // 复制索引1开始到索引4(但不包括索引4)的元素,arr2的元素会是2,3,4

     

    Arrays    //记得加s!

    Array类位于java.util包中,它提供了几个方法可以直接使用:

    sort() - 对指定数组排序,作用是快速排序法

    使用方法:用一个例子就可以说清楚:int[] arr={1,4,6,3,9,7};

    使用类里面的方法:Arrays.sort(arr);之后数组的值会从小到大排列 arr={1,3,4,7,9};

     

    binarySearch() - 让你对已排序的数组进行二分查找,如果找到指定的值就返回该值所在的索引,否则就返回负值

    使用方法介绍:也是用上面一个数组来说:intnum=Arrays.binarySearch(arr6);那么num=2

    需要注意的是:括号里面有两个参数:第一个是数组名称,第二个是要在数组中查找的元素,

    如果数组中没有这个元素就返回一个负数,否则返回的值是数组元素游标的值

     

    fill() - Arrays.fill()将已创建数组的默认值改为指定值

    使用:Arrays.fill(arr,3);使用后arr数组里面的全部值都变成3

     

    Arrays.equals() - 比较两个数组中的元素值是否全相等,如果相等返回true,否则返回false

     boolean b=Arrays.equals(arr1,arr2);

     

    Arrays.toString()- 可以一次输出数组的元素,每个元素之间用逗号相隔

    System.out.println(Arrays.toString(arr));

     

    Arrays类里面还有很多其他的封装的方法,如果有兴趣的话可以查看相关文档或浏览API

     

    foreach与数组

    Java SE 6中, foreach的语法为:

    int[] arr ={1,2,3,4,5};

    for(int element : arr){

    System.out.println(element);

    }

        结果将会依次输出数组arr里面的值

    注意, element类型必须与数组元素类型相同

     

    三、数组的编程题目

     

    数组用于数字取位的一个应用:

    比如输入一个4位数s:求它个十百千位的数字

    Int[ ] arr=new int[ 4 ];

    for(int i=3;i>=0;i--){

           arr[i]=s% 10;

           s= s / 10;

    }

    那么:arr[0] 、arr[1]、 arr[2] 、arr[3],分别是这个数的千、百、十、个位的数字 

     

    数组遍历主要是搭配for循环使用的


    下面的编程题目,除了第一题,其他几题逻辑性是有点强的

     

    程序示例1

    题目:给一个不多于5位的正整数,要求:一、求它是几位数,二、逆序打印出各位数字。

    程序分析:创建一个五位数数的数组,把输入数字的每位数的值赋值到数组里面  

          * 把输入 数字从个位起获取,并且每获取一次之后/10,这样就能分别获取十位百位千位了

          * 把数字打印出来就是题目所求了 

    public class Programme24 {

        public static void main(String[] args) {

           System.out.println("请输入一个不大于5位数的数字:");

           Scanner scanner=new Scanner(System.in);

           int num=scanner.nextInt();//获取输入

           int[] arr=new int[5];//创建5位数的数组

           int i=0;

           //循环取位

           do{     

                arr[i]=num%10;

                num=num/10;

                i++;

           }while (num!=0);//只剩下一位时,说明获取完毕,跳出循环

           System.out.println("输入数字串的是"+i+"位数的");

           System.out.println("逆序输出:");

           //打印出数组

           for (int j = 0; j < i;j++) {

               System.out.print(arr[j]+"  ");

           }

           scanner.close();

        }

    }

     

     

     

    程序示例2

    题目:对10个数进行排序

    程序分析:可以利用选择法,即从后9个比较过程中,选择一个最小的与第一个元素交换,下次类推,即用第二个元素与后8个进行比较,并进行交换。

    最后打印出来的数组就是从小到大排列的数组了

     

    public class Programme28 {

        public static void main(String[] args) {

           System.out.println("请输入10个数(用空格隔开):");

           int[] arr=new int[10];

           Scanner scanner=new Scanner(System.in);

           for (int i = 0; i < 10; i++) {

               arr[i]=scanner.nextInt();

           }

           //对数组进行排序

           int temp=0;//交换数

           for (int i = 0; i < 9; i++) {

               for (int j = i+1; j < arr.length; j++) {

                  if (arr[i]>arr[j]) {   //如果第一个数比后面的数大就交换

                      temp=arr[i];

                      arr[i]=arr[j];

                      arr[j]=temp;

                  }

               }

           }

    //对数组排序也可以用封装的方法:Arrays.sort(arr);

           System.out.println("排列后的数组:"+Arrays.toString(arr));//Arrays类的包装方法!

        }

    }

     

     

     

    程序示例3

    题目:打印出杨辉三角形(要求打印出10行如下图)

    程序分析:

        1

       1 1

        1 2 1

    1 3 3 1

     1 4 6 4 1

    1 5 10 10 5 1

    1、二维数组的使用

    2、第一列的数都是1

    3、使用两个for循环,i控制行,j控制列;

    从第二行第二列起arr[i][j]=arr[i-1][j-1]+arr[i-1][j]

    public class Programme33 { 

    public static void main(String[] args) {

            int[][] arr=new int[10][10];

            for (int i = 0; i < arr.length; i++) {

                arr[i][0]=1;//控制第一列的数等于1

           }

           for (int i = 1; i < arr.length; i++) {

               for (int j=1; j < arr.length; j++) {

                  arr[i][j]=arr[i-1][j-1]+arr[i-1][j];//赋值

               }

           }

           //打印结果

           for (int i = 0; i < arr.length ; i++) {

               for (int k = arr.length-i;k>0; k--) {//空格的控制,为了好看

                  System.out.print("  ");

               }

               for (int j = 0; j < arr.length; j++) {//打印出数组的数字

                  if (arr[i][j]!=0) {//把把没赋值的零去掉

                      System.out.print(arr[i][j]+"   ");

                  }

               }

               System.out.println();//控制换行

           }

        }

    }

     

     

    程序示例4

    题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。

    关键问题是怎么移除》?:布尔值确定,如果被选中被赋值为false

         * 从第一个人开始判断,如果他在圈内,那么报数,再判断他报的数是否是3,如果是的话移出圈外

         * 接着判断下一个人,是否到了最末,如果是的话,从零开始

         * 不断循环,直到最后剩下1个人

        public static void main(String[] args) {

           System.out.print("请输入一个整数:");

           Scanner scan = new Scanner(System.in);

           int n = scan.nextInt();

           scan.close();

           //定义数组变量标识某人是否还在圈内

           boolean[] isIn = new boolean[n];

           for(int i=0;i<isIn.length;i++){

                 isIn[i] = true;

           }

           int inCount = n;//定义圈内人数

           int countNum = 0;//定义报数

           int index = 0;//定义索引

           while(inCount>1){//最后一人时退出循环

               if(isIn[index]){//判断下一个人是否在圈内

                  countNum++;//在的话报数

                  if(countNum==3){//如果这个数等于3

                      isIn[index] = false;//把他定义为出圈

                      countNum = 0;//报数清零,下一个好从1开始

                      inCount--;//圈内人数减一

                  }

               }

               index++;//下一人的位置索引值

               if(index==n){//当索引到最后之后再从头开始

                   index = 0;

               }

           }

           for(int i=0;i<n;i++){

               if(isIn[i]){//最后只有一个符合条件的

                  System.out.println("留下的是:"+(i+1));

               }

           }

        }

    }

     

     

    程序示例5

    题目:有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。

    程序分析:首先判断此数是否大于最后一个数,然后再考虑插入中间的数的情况,插入后此元素之后的数,依次后移一个位置。

    1、创建两个数组,如果插入的数字比数组最后一个都大,那么插入的数放在新数组最后就可以

          * 2、如果插入的不是最大,那么和数组前面的数逐一比较,比较到比插入的数大就break

          *  比如第i个符合条件,那么arrB[i-1]=arrA[i-1],arrB[i]=num,arrB[i+1]=arrA[i]

        public static void main(String[] args) {

           System.out.println("请输入一个数字:");

           Scanner scanner=new Scanner(System.in);

           int num=scanner.nextInt();

           int[] arrA={3,5,15,36,84,99};

           int[] arrB=new int[arrA.length+1];

           if (num>arrA[arrA.length-1]) {

               for (int i = 0; i < arrA.length; i++) {

                  arrB[i]=arrA[i];

               }

               arrB[arrB.length-1]=num;

           }else {

               for (int i = 0; i < arrA.length; i++) {

                  if (num<arrA[i]) {

                      for (int j = 0; j < i; j++) {

                         arrB[j]=arrA[j];

                      }

                      arrB[i]=num;

                      for (int j = i; j < arrA.length; j++) {

                         arrB[j+1]=arrA[j];

                      }

                      break;//这个很重要

                  }

               }

           }

           System.out.println("插入一个数后的数组为:"+Arrays.toString(arrB));

           scanner.close();

        }

    }

     

     

    展开全文
  • Java数组

    千次阅读 多人点赞 2018-07-28 09:59:47
    Java 语言中提供的数组是用来存储固定大小的同类型元素。 数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。 数组属引用类型,数组型数据是对象(object),数组中的每个元素相当于该对象的成员...

    数组介绍

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

    数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。

    数组属引用类型,数组型数据是对象(object),数组中的每个元素相当于该对象的成员变量。

    数组是多个相同类型数据的组合,实现对这些数据的统一管理。一个数组实际上就是一连串的变量,数组按照使用可以分为一维数组、二维数组、多维数组。

     

    要使用Java的数组,必须经过两个步骤:

    1)声明数组变量

    2)创建数组:分配内存给这个数组

     

    声明数组

    首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:

    元素类型[] 数组名;  // 建议使用的方式
    元素类型 数组名[];  // 效果相同,这种风格类似 C/C++ 语言 

    “数组名”是用来统一这组相同数据类型的元素的名称,建议使用有意义的名称为数组命名。

    int[] score = null;  // 推荐方式,null表示引用数据类型的默认值
    // int socre[] = null;  // 非推荐方式
    

     

    为数组开辟空间

    数组声明后实际上是在栈内存中保存了此数组的名称,接下来便是要在堆内存中配置数组所需的内存,其中“元素的个数”(数组的长度)是告诉编译器,所声明的数组要存放多少个元素,而“new”则是命令编译器根据括号里的长度开辟空间。

    数组名 = new 元素类型[元素的个数];

    我们为上面声明的socre数组开辟空间:

    score = new int[3];

    数组操作中,在栈内存中保存的永远是数组的名称,只开辟了栈内存空间数组是永远无法使用的,必须有指向的堆内存才可以使用,要想开辟新的堆内存则必须使用new关键字,之后只是将此堆内存的使用权交给了对应的栈内存空间,而且一个堆内存空间可以同时被多个栈内存空间指向,即:一个人可以有多个名字,人就相当于堆内存,名字就相当于栈内存。

     

    数组的动态初始化

    声明数组的同时分配内存:

    元素类型 数组名[] = new 元素类型[元素的个数];

    下面我们声明一个元素个数为10的整型数组score,同时开辟一块内存空间供其使用:

    int[] score = new int[10];

    在Java中,由于整数数据类型所占用的空间为4个bytes,而整型数组score可保存的元素有10个,所以上例中占用的内存共有4 * 10 = 40个字节。

    数组是引用类型,它的元素相当于类的成员变量,因此数组一经分配空间,其中的每个元素也被按照成员变量同样的方式被隐式初始化

    public class ArrayTest {
        public static void main(String[] args) {
             // 对各元素进行初始化,但没有赋值。
            String[] stringArray = new String[3]; // 各元素的值默认为String类型的初始值null
            // 数组没有length()这个方法,有length的属性。
            for (int i = 0; i < stringArray.length; i++) {
                System.out.println(stringArray[i]);  // null null null
            }
        }
    }

     

    数组中元素的表示方法

    想要访问数组里的元素,可以利用索引来完成。Java的数组索引编号由0开始,以一个的score[10]的整形数组为例,score[0]代表第1个元素,score[1]代表第2个元素,score[9]为数组中第10个元素(也就是最后一个元素)。

    程序中可以发现,对于数组的访问采用“数组名称[下标]”的方式,之前一共开辟了三个空间大小的数组,所以下标的取值是0~2,假设程序中取出的内容超过了这个下标,如“score[3]”,则程序运行的时候会出现数组下标越界的错误提示:java.lang.ArrayIndexOutOfBoundsException。

     

    为数组中的元素赋值并进行输出:

    public class Test {
        public static void main(String[] args) {
            int score[] = null; // 【1】声明数组,但未开辟堆内存
            score = new int[3]; // 【2】为数组开辟堆内存空间,大小为3
            for (int x = 0; x < score.length; x++) { // 数组的长度可以用“数组名.length”
                score[x] = x * 2 + 1 ; // 为每一个元素赋值
            } // 【3】开辟堆内存空间结束
            for (int x = 0; x < 3; x++) { // 使用循环依次输出数组中的全部内容
                System.out.println("score[" + x + "] = " + score[x]);
            }
        }
    }

    我们对以上代码进行内存分析,【1】【2】【3】处分别对应下面这三张图:

     

    数组的静态初始化

    数组的内容分为动态初始化和静态初始化两种,前面所讲解的全部代码是采用先声明数组之后为数组中的每个内容赋值的方式完成的。那么也可以通过数组静态初始化在数组声明时就为数组元素分配空间并赋值。

    元素类型 数组名 = {元素1,元素2...};
    元素类型 数组名 = new 元素类型[]{元素1,元素2...};

    数组的元素是通过索引访问的。数组索引从 0 开始,所以索引值从 0 到数组长度-1。

     

    处理数组

    数组的元素类型和数组的大小都是确定的,所以当处理数组元素时候,我们通常使用基本循环,尤其是for循环。JDK 1.5 引进了一种新的循环类型,被称为 foreach 循环或者加强型循环,它能在不使用下标的情况下遍历数组。

    public class TestArray {
       public static void main(String[] args) {
          double[] arr = {1.5, 2.5, 3.5, 3.5, 5.5};
          // 打印所有数组元素
          for (double element: arr) {
             System.out.println(element);
          }
       }
    }

    数组和前面讲到的八种基本数据类型一样也是一种数据类型,只不过它和后面要讲到的类、接口一样都是引用类型。既然是数据类型,那么就可以作为方法的参数类型(比如main方法的 string[] args)、方法的返回值类型使用,这个我们在方法篇再举例说明。

     

    多维数组

    多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。我们以二维数组为例看一下多维数组的初始化:

    二维数组的动态初始化:直接为每一维分配空间

    元素类型 变量名 = new 元素类型[行数][列数];

    声明整型数组score,同时为其开辟一块内存空间:

    int[][] score = new int[4][3];

    整型数据score可保存的元素有4*3 = 12个,而在Java中,int数据类型所占用的空间为4个字节,因此该整型数组占用的内存共为4*12 = 48个字节。

    public class Test {
        public static void main(String[] args) {
            int score[][] = new int[4][3]; // 声明并实例化二维数组
            score[0][1] = 30 ; // 为数组中的部分内容赋值
            score[1][0] = 31 ; // 为数组中的部分内容赋值
            score[2][2] = 32 ; // 为数组中的部分内容赋值
            score[3][1] = 33 ; // 为数组中的部分内容赋值
            score[1][1] = 30 ; // 为数组中的部分内容赋值
            for (int i = 0; i < score.length; i++) { // 外层循环行
                for(int j=0;j<score[i].length;j++){// 内层循环列
                    System.out.print(score[i][j] + "\t");
                }
                System.out.println("") ; // 换行
            }
        }
    }
    

    执行结果如下:

    0	30	0	
    31	30	0	
    0	0	32	
    0	33	0	

     

    二维数组的静态初始化:

    元素类型 变量名 = {{元素A1,元素A2...}, {元素B1,元素B2}...};

    例如

    int score[][] = {{ 67, 61 }, { 78, 89, 83 }, { 99, 100, 98, 66, 95 }};

    一般来讲,操作二维数组不应使用常数来控制维数。具体方法是array.length表示行数,array[row].length来表示row行的列数。这样当数组行数和列数不相等时,代码可以自动调整为正确的值。

    public class Test {
        public static void main(String[] args) {
            // 静态初始化一个二维数组,每行的数组元素个数不一样
            int[][] score = {{ 67, 61 }, { 78, 89, 83 }, { 99, 100, 98, 66, 95 }};
            for (int i = 0; i < score.length; i++) { // 外层循环输出行
                for (int j = 0; j < score[i].length; j++) {// 内存循环输出列
                    System.out.print(score[i][j] + "\t");// 输出每一个元素
                }
                System.out.println(""); // 换行
            }
        }
    }
    

    执行结果如下:

    67	61	
    78	89	83	
    99	100	98	66	95

     

    操作数组的工具类:Arrays

    java.util.Arrays类包含了用来操作数组(比如排序和搜索)的各种方法,它提供的所有这些方法都是静态的。

    Arrays拥有一组static方法:

    序号方法和说明
    1public static int binarySearch(Object[] a, Object key)
    用二分查找算法在给定数组中搜索给定值的对象(Byte,Int,double等)。数组在调用前必须排序好的。如果查找值包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。
    2public static boolean equals(long[] a, long[] a2)
    如果两个指定的 long 型数组彼此相等,则返回 true。如果两个数组包含相同数量的元素,并且两个数组中的所有相应元素对都是相等的,则认为这两个数组是相等的。换句话说,如果两个数组以相同顺序包含相同的元素,则两个数组是相等的。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。
    3public static void fill(int[] a, int val)
    将指定的 int 值分配给指定 int 型数组指定范围中的每个元素。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。
    4public static void sort(Object[] a)
    对指定对象数组根据其元素的自然顺序进行升序排列。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。
    public class Test {
        public static void main(String[] args) {
            int array[] = { 2, 5, 8, 3, 1, 4, 9, 6, 7 }; // 声明一个整型数组
            System.out.println("Object的toString:"array.toString()); //Object的toString()方法
            Arrays.sort(array);  // 数组排序
            System.out.println("排序后的数组: " + Arrays.toString(array)) ; 
            int point = Arrays.binarySearch(array, 3) ; // 检索数据位置
            System.out.println("元素‘3’的位置在:" + point) ;
            Arrays.fill(array, 6) ; // 填充数组
            System.out.print("数组填充:" + Arrays.toString(array)) ;
        }
    }

    执行结果:

    Object的toString:[I@7852e922
    排序后的数组: [1, 2, 3, 4, 5, 6, 7, 8, 9]
    元素‘3’的位置在:2
    数组填充:[6, 6, 6, 6, 6, 6, 6, 6, 6]

    System.arraycopy()array的复制。    

    使用System.arraycopy()方法进行数组拷贝,可以提高性能。

    public class Test {
        public static void main(String[] args) {
            int[] a = { 3, 5, 6, 12, 45 }; // 声明一个整型数组a
            int[] b = { 23, 12, 4, 53, 2}; // 声明一个整型数组b
            System.arraycopy(a, 1, b, 2, 2);
            System.out.println("数组a: " + Arrays.toString(a));
            System.out.println("数组b: " + Arrays.toString(b));
        }
    }

    执行结果:

    数组a: [3, 5, 6, 12, 45]
    数组b: [23, 12, 5, 6, 2]

     

     

     

    展开全文
  • Java数组详解

    千次阅读 2020-04-09 21:56:46
    Java数组详解 本文将介绍Java数组的一些基本语法及应用,如java一维数组,二维数组的声明,分配空间,数组访问,赋值,数组排序,查找等等。 数组定义 数组是相同数据的有序集合,简单来说,就是将若干相同元素按...

    Java数组详解

    本文将介绍Java数组的一些基本语法及应用,如java一维数组,二维数组的声明,分配空间,数组访问,赋值,数组排序,查找等等。

    数组定义

    数组是相同数据有序集合,简单来说,就是将若干相同元素按一定的次序存放在一起。其特点如下:

    1. 数组存放元素类型必须相同不能有混合类型
    2. 数组各元素按先后顺序有序的存放在内存中,每个元素通过数组名和下标来访问。
    3. 数组的长度固定,一旦创建,无法进行修改。
    4. 数组元素类型可以是任何类型,包括基本类型引用类型(类、接口、数组)。

    数组声明

    定义了一个数组的名称、维数及数组元素的类型

    int[] a;//推荐使用
    int a[];
    

    (此时仅在栈内存分配空间,并没有实例化对象,因此堆内存并未使用)
    在这里插入图片描述

    数组初始化

    静态初始化

    int[] a = {1,4,3,3,2,3,3};
    //int类型数组
    Boy[] b = {new Boy(18,180),new Boy(17,178)};
    //引用类型数组,将Boy类实例化对象初始化给b数组
    

    动态初始化

    int[] c = new int[5];
    c[0] = 233;
    //先给数组分配空间,然后对各个元素赋值
    

    初始化默认值

    //初始化时会给每个元素赋予一个默认的值
    int[] score = new int[2];//默认为0,0
    String[] name = new String[2];//默认null,null
    boolean[] chioce = new boolean[2];//默认false,false
    

    (当数组类型为引用类型,默认值为null,当你访问其属性的时候,必须进行初始化,否则会报空指针异常)

    在这里插入图片描述
    在这里插入图片描述

    数组的遍历

    我们可以使用for循环来对数组进行动态初始化及元素的访问

    public class Test {
        public static void main(String[] args) {
            int[] a = new int[4];
            //初始化数组元素的值
            for(int i=0;i<a.length;i++){
            //a.length可得到数组元素的个数
                a[i] = i;
            }
            //读取元素的值
            for(int i=0;i<a.length;i++){
                System.out.println(a[i]);
            }
        }
    }
    

    结果:
    结果

    增强for循环

    对于数组,和含有一组元素的集合,可使用增强for循环进行遍历,但是在遍历时不能对数组元素进行修改

    String[] str= {"aa","bb","cc","dd"};
    for (String temp:str) {
    			System.out.println(temp);
    		}
    

    结果:
    在这里插入图片描述

    二维数组

    二维数组相当于在一维数组的基础上,每个元素中有一个一维数组

    声明

    int[][] a;
    int b[][];
    

    初始化

    int[][] c = new int [3][];
    //int[][] d = new int [][3];//错误
    int [][] e = new int{
    						{ 1, 2, 3 },
     						{ 3, 4 },
      						{ 3, 5, 6, 7 }
      						};//静态初始化
    int d[0] = {1,2,3};//动态初始化
    int d[1] = {2,1,5};
    

    空间分配:
    在这里插入图片描述
    当学完数组的这些基本知识后,我不由产生了一个大胆的想法,能不能将不同类型的数据放到同一个数组中呢?
    在这里插入图片描述
    这时你一定会反驳我,不是一开始就讲明了数组的特性就是只能存放同一类型的元素?
    我们先分析数组存放的原理,同一类型元素才能存于同一数组,我们做个比喻,将数据比作各种规则物体,整型为正方体,长整型则是更大的正方体,字符串为球体,根据数组的特点,把数组当做一个箱子,我们规定只有同样形状的物体能放进同样形状的箱子中。
    在这里插入图片描述
    这样似乎我们无法将不同类型元素放在一起。但是,我们知道Object是所有类的基本,所谓万物基于Object。我们的确不能将不同类型的元素放于一个数组,但是我们可以将不同类型的元素向下转型为Object,这样相当于所以元素的类型都变得“一样”了,自然可以存放于同一数组。

    Object[] x1 = {1001,"A",18};
    Object[] x2 = {1002,"B",17};
    Object[] x3 = {1003,"C",19};
    Object[][] tableData = new Object[3][];
    table[0] = x1;
    table[1] = x2;
    table[2] = x3;
    

    将数组打印结果如下:
    在这里插入图片描述

    数组工具类Arrays

    在该类中封装了一些对数组操作的静态方法

    sort方法排序

    int[] num = {4,5,3,2};
    for(int i:num) {
    	        	System.out.print(i+",");
    	        }
    System.out.println();
    Arrays.sort(num);
    for(int i:num) {
    	        	System.out.print(i+",");
    	        }
    

    结果:
    在这里插入图片描述
    toString方法将数组转换成字符串,可直接将数组输出

    System.out.println(Arrays.toString(num));
    

    直接将上面的num数组输出:
    在这里插入图片描述
    那么二维数组可以直接输出吗?我们进行尝试:

    int[][] num2 = {{1,22,3},{4,8,0}};
    System.out.println(Arrays.toString(num2));
    

    结果:
    在这里插入图片描述
    显然是不行的,我们只能访问到数组的引用地址。这时候Arrays类提供了deepToString方法可以实现这一功能:

     System.out.println(Arrays.deepToString(num2));
    

    结果:
    在这里插入图片描述

    注意:这里的toString()方法与类里面的toString方法重名,但是没有一点关系。

    数组的复制

    数组的复制是创建新的空间如何将数组复制过去
    Arrays提供了两个静态方法:
    copyOf(array,length)从被复制数组首位置开始,复制length长度
    copyOfRange(array,start,end)从被复制数组start下标开始复制,到end结束(不包括end,所以是[start,end)左开右闭

    int[] num3 = {1,2,3,4,5,6};
    int[] num4 = Arrays.copyOf(num3, 2);
    int[] num5 = Arrays.copyOfRange(num3, 2, 5);
    System.out.println(Arrays.toString(num4));
    System.out.println(Arrays.toString(num5));
    

    结果:
    在这里插入图片描述

    展开全文
  • 本章小结了Java数组的基本语法,分享给新学习的小伙伴,分享获取新知大家一起进步。 文章目录一.引言二.数组三.数组的使用四.数组的内存分配 一.引言 回顾数据类型: (1)基本类型 byte short int long float ...
  • Java 数组

    2016-05-10 15:37:58
    Java 数组一维数组 几个概念 数组一种数据结构,用来存储元素个数固定,元素类型相同的有序集。基本知识 声明数组 指定数组的元素类型,并不在内存中给数组分配任何空间,只是创建一个对数组的引用的存储位置,...
  • 【Java】探究Java数组的本质

    千次阅读 2020-01-25 14:18:46
    深入地剖析一下Java数组的本质
  • java 数组

    2017-07-10 08:38:54
    原生类有8种, int double boolean float byte short long charjava数组的长度不可以改变。 java中的数组的定义就是相同类型,固定长度的一组数据,一旦被初始化,长度不可更改。如果对需要用的数组的长度不确定...
  • Java数组备忘录

    千次阅读 2015-06-28 11:53:40
    前言最近用Java做ACM题目的时候,经常忘记数组如何实现静态初始化,所以这里记录一下Java数组使用的常识。Java数组常识数组在Java中是一个对象,数组实例需要通过new操作符进行创建。常识知识: 数组大小可以通过...
  • Java数组超详解

    千次阅读 多人点赞 2021-09-27 10:47:55
    前面我们学习了随机数的介绍和使用,那么这篇我们来学习java数组的定义和使用, java数组和c语言的十分类似。 二、数组的定义 数组定义的形式: 格式1: 数据类型 [ ] 数组名 ;如int [ ]arr; 说明:...
  • Java数组之数组的类型

    2016-03-15 22:14:08
    Java数组之数组的类型在Java中,数组也是引用类型,在创建时被分配到堆内存上。数组是特殊的类,但Java中并没有定义它的类路径。若仿照通常定义数组的语法,我们来加载数组:Class.forName("java.lang.String[]");...
  • JAVA 数组

    千次阅读 2020-03-12 21:25:33
    数组 数组是一种数据结构, 用来存储同一类型值的集合。 一旦创建了数组, 就不能再改变它的大小(尽管可以改变每一个数组元素)。 通过一个整型下标可以访问数组中的每一个值。例如, 如果 a 是一个整型数组, a[i] ...
  • JAVA数组详解

    千次阅读 2013-03-06 19:08:58
    最近看了一些关于java数组的资料,在此总结一下: 一、数组的定义和类型:  数组就是类型相同的数据对象元素集合。简单的说:就是类型相同的数据存储在一个容器里面【注意:Java中的数组是引用类型,即使一个数组中...
  • 不会用的Java数组,从青铜到王者,全解析数组,建议收藏!!!
  • Java基础——数组 Java基础知识 数组 1.数组简介 数组是用来存储相同数据类型的一组数据 声明一个变量就是在内存中划出一块空间 声明一个数组就是在内存中划出一串连续的空间 数组的四要素: 数组名称:用来区分...
  • Java数组插入或删除元素

    万次阅读 多人点赞 2018-04-09 00:44:21
    Java数组常见操作练习 Java数组插入或删除元素 **练习1.随机生成一个整数型数组(1-10数组长度随机,0-50数组元素随机) 在其数组的最后追加一个1-50随机数值** public class ArrayInsert1{ public static ...
  • [精]JAVA数组的内存结构详解

    万次阅读 2016-10-31 14:07:32
    Java 数组是静态的Java 语言是典型的静态语言,因此 Java 数组是静态的,即当数组被初始化之后,该数组 所占的内存空间、数组长度都是不可变的。Java 程序中的数组必须经过初始化才可使用。所 谓初始化,即创建实际...
  • Java数组与内存控制

    千次阅读 2013-01-24 16:47:00
    一、Java数组初始化  Java数组是静态的,即当数组被初始化之后,该数组的长度是不可变的。Java数组使用之前必须先对数组对象进行初始化,所谓初始化,就是为数组的所有元素分配内存空间,并为每个数组元素指定...
  • Java数组基本操作

    千次阅读 多人点赞 2018-02-21 13:47:32
    数组声明 数组初始化 遍历数组 Arraysfill填充数组 ...java打印数组 定位元素位置 数组声明 数组声明有如下两种形式(方括号的位置不同): int arr[]; int[] arr2; 数组初始化 数...
  • java.lang.reflect.Array类提供了通过静态方法来动态创建和访问Java数组的操作。 1.主要的静态方法 java.lang.reflect.Array提供以下几类静态方法操作: Array.newInstance() :创建引用类型的数组 Array.set...
  • Java数组去重

    千次阅读 2016-03-16 13:38:44
    import java.util.Arrays; import java.util.HashSet; import java.util.Set; public class Demo5 { /** * 数组去重 * @author LinBilin * @param arr 需要去重的数组 * @return 返回数组 */ @Supp
  • 学习Java,你需要知道这些——Java数组

    千次阅读 多人点赞 2020-04-25 16:36:22
    数组的概念 数组由同一类型的对象或者基本数据组成,并封装在同一一个标识符(数组名称)下。 数组是对象 动态初始化 可以赋值给Object类型的变量 在数组中可以调用类Object的所有方法 二每个数组都有一 个...
  • ![图片说明](https://img-ask.csdn.net/upload/201711/19/1511066739_344598.png)
  • 1.声明java数组要不能声明为int a[10]; 否则会在编译时出错Syntax error on token "10", delete this token2.赋值第一种方式int a[]=new int[2];这样直接在堆中创建数组对象赋给引用a; 第二种方式int a[]={2,2,2}...
  • Java数组类型

    万次阅读 2018-07-13 17:27:28
    数组是一种数据结构,用来存储同一类型之的集合。通过一个整形下标可以访问数组中的每一个值。在声明数组变量时,需要指出数据类型和数组变量的名字。下面声明了整形数组a:int[] a;这条语句之声明了变量啊,病没有...
  • Java数组与方法

    千次阅读 2019-04-29 16:31:14
    ** 一维数组 ** 数组的初始化:静态初始化、动态初始化 静态初始化:在声明时指定数组内容 数组类型 数据名[] = {初始值1,...0.0 , boolean[]->false , char[]->编码为0的控制字符 数组堆与栈 ** 二维数...
  • JAVA数组及数组的应用

    千次阅读 多人点赞 2017-09-04 17:55:04
    一、数组 一组数的容器。 数组对每一个存入的数字都会自动编号,编号从0开始。——下标 二、数组的定义格式 Type[] name = new Type[size] 数组的大小一旦被定义,不可改变。 在程序中第一次给变量赋值—–变量的...
  • java数组初始化以及数组拷贝

    千次阅读 2017-03-20 18:19:54
    //这里创建了一个可以存储100个整数的数组,当创建数值数组时,所有的元素都被初始化为0,boolean数组初始化为false,对象数组初始化为null值 2.数组的初始化  int[] a = {2,4,5,7,8};//数组的长度由

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 466,262
精华内容 186,504
关键字:

java数组boolean

java 订阅