>  기사  >  Java  >  Java에서 배열의 정의와 사용에 대해 이야기해 보겠습니다.

Java에서 배열의 정의와 사용에 대해 이야기해 보겠습니다.

WBOY
WBOY앞으로
2022-07-11 12:05:222066검색

이 기사에서는 java에 대한 관련 지식을 제공합니다. 이는 기본 메소드의 문자열 배열, 배열의 참조 데이터 유형 저장, 배열 확장 및 복사를 포함하여 배열의 정의 및 사용과 관련된 문제를 주로 정리합니다. 아래 내용이 모든 분들께 도움이 되기를 바랍니다.

Java에서 배열의 정의와 사용에 대해 이야기해 보겠습니다.

추천 학습: "java 비디오 튜토리얼"

1차원 배열

Java 언어의 배열은 참조 데이터 유형입니다. 부모 클래스입니다. 배열 Object입니다.
배열은 실제로 여러 요소를 동시에 담을 수 있는 컨테이너입니다. (배열은 데이터의 집합입니다.)
배열: 말 그대로 "데이터의 집합"을 의미합니다.
배열은 "기본 데이터 유형"의 데이터와 "참조 데이터 유형"의 데이터를 저장할 수 있습니다.
배열은 참조형이므로 배열 객체는 힙 메모리에 있습니다. (배열은 힙에 저장됩니다.)
배열에 "java 객체"가 저장되어 있으면 실제로 저장되는 것은 객체의 "참조(메모리 주소) "입니다. Java 객체는 배열에 직접 저장할 수 없습니다. (주소를 저장하세요).

배열이 생성되면 Java에서는 길이를 변경할 수 없다고 규정합니다. (배열 길이는 불변)
배열의 분류: 1차원 배열, 2차원 배열, 3차원 배열, 다차원 배열...(1차원 배열이 더 일반적이며 2차원 배열이 가끔 사용됨) !)
모든 배열 객체에는 배열의 요소 수를 가져오는 데 사용되는 length 속성(java가 함께 제공됨)이 있습니다.
Java의 배열에서는 배열의 요소 유형이 균일해야 합니다. 예를 들어 int 유형 배열은 int 유형만 저장할 수 있고 Person 유형 배열은 Person 유형만 저장할 수 있습니다. 예를 들어, 슈퍼마켓에서 쇼핑할 때 사과와 오렌지를 동시에 넣을 수는 없고 쇼핑백에 사과만 넣을 수 있습니다. (배열에 저장되는 요소의 유형은 동일합니다.)
배열이 메모리에 저장될 때 배열에 있는 요소(저장된 각 요소는 규칙적으로 나란히 배열됨)의 메모리 주소는 연속적입니다. 메모리 주소는 연속적입니다. 이것이 요소를 저장하는 배열의 특징(특징)입니다. 배열은 실제로 간단한 데이터 구조입니다.
모든 배열은 "첫 번째 작은 상자의 메모리 주소"를 전체 배열 개체의 메모리 주소로 사용합니다. (배열의 첫 번째 요소의 메모리 주소는 전체 배열 객체의 메모리 주소로 사용됩니다.)
배열의 각 요소에는 첨자가 있으며, 첨자는 0부터 시작하여 1씩 증가합니다. 마지막 요소의 첨자는 다음과 같습니다. length - 1 첨자는 배열의 요소에 "접근"할 때 첨자를 사용해야 하기 때문에 매우 중요합니다.
Array이 데이터 구조의 장점과 단점은 무엇인가요?
장점: 특정 첨자의 요소를 쿼리/찾기/검색할 때 매우 효율적입니다. 쿼리 효율성이 가장 높은 데이터 구조라고 할 수 있습니다. 검색 효율이 왜 이렇게 높나요?
첫째: 각 요소의 메모리 주소는 공간 저장 측면에서 연속적입니다.
둘째: 각 요소는 동일한 유형이므로 동일한 공간을 차지합니다.
셋째: 첫 번째 요소의 메모리 주소, 각 요소가 차지하는 공간의 크기 및 첨자를 알면 특정 첨자 위의 요소의 메모리 주소를 수학적 표현식을 통해 계산할 수 있습니다. 메모리 주소를 통해 직접 요소를 찾으므로 배열 검색 효율성이 가장 높습니다. 100개의 요소가 배열에 저장되거나, 100만 개의 요소가 저장될 때 배열의 요소를 하나씩 검색하는 것이 아니라 수식을 통해 계산하기 때문에 요소 조회/검색 측면에서 효율성은 동일합니다. (메모리 주소를 계산해서 직접 찾아보세요.)
                  단점 :
                        1: 배열의 각 요소의 메모리 주소가 연속성을 보장하기 때문에 배열에 요소를 무작위로 삭제하거나 추가할 때 효율성이 떨어집니다. 낮은 이유는 무작위로 요소를 추가하고 삭제하면 후속 요소가 앞으로 또는 뒤로 변위되기 때문입니다.
                  둘째: 배열은 많은 양의 데이터를 저장할 수 없습니다. 이유는 무엇입니까? 왜냐하면 메모리 공간에서 특별히 큰 연속 메모리 공간을 찾기가 어렵기 때문입니다. 배열의 마지막 요소를 추가하거나 삭제해도 효율성에는 영향이 없습니다.

1차원 배열을 어떻게 선언/정의하나요?
문법 형식:

int[] array1;
double[] array2;
boolean[] array3;
String[] array4;
Object[] array5;

1차원 배열을 초기화하는 방법은 무엇인가요?
여기에는 1차원 배열의 정적 초기화와 1차원 배열의 동적 초기화라는 두 가지 방법이 포함됩니다.
          (1) 정적 초기화 문법 형식:
              int[] array = {100, 2100, 300, 55};
                  (2) 동적 초기화 구문 형식 :
    int[] 배열 = 새로운 int[ 5];

                                                                                                 :
              5 길이의 int 유형 배열을 초기화합니다. 각 요소의 기본값은 0입니다.
                              또 다른 예: String[] names = new String[6];

정적 배열 초기화는 언제 사용하나요? 동적 배열 초기화는 언제 사용합니까?

(1) 키 배열을 생성할 때 어떤 특정 요소가 배열에 저장되어 있는지 결정할 때 정적 초기화를 사용하세요.

(2) 키 배열을 생성할 때 앞으로 어떤 데이터가 저장될지 확실하지 않은 경우, 동적 초기화를 사용할 수 있습니다

package com.bjpowernode.javase.array;

public class ArrayTest01 {
    public static void main(String[] args) {
    //1.静态初始化
       int[] a1 = {1,3,5,7,9};
        //所有的数组对象都有length属性,而不是方法!
        System.out.println("数组元素的个数是:"+a1.length);
        //取第一个元素
        System.out.println(a1[0]);
        //取最后一个元素
        System.out.println(a1[a1.length-1]);
        //改数据
        a1[a1.length-1] = 0;
        //遍历数据
        for(int i=0;i< a1.length;i++){
            System.out.println(a1[i]);
        }
        //数据下标越界异常,例如:访问下面为6的数据元素
        //System.out.println(a1[6]);// ArrayIndexOutOfBoundsException


    //2.动态初始化
        int[] a2 = new int[5]; //默认值是0
        for(int i=0;i< a2.length;i++){
            System.out.println(a2[i]);
        }
        //初始化一个Object类型的数组,
          //1.采用静态初始化方式
        Object o1 = new Object();
        Object o2 = new Object();
        Object o3 = new Object();
        Object[] object = {o1,o2,o3};
        //上面就等价于:Object[] object = {new Object(),new Object(),new Object()};
        for(int i=0;i<object.length;i++){
            System.out.println(object[i]);// 默认调用toString方法
        }
          //2.采用动态初始化的方式
        Object[] obj = new Object[3];
        for(int i=0;i<obj.length;i++){
            System.out.println(obj[i]);// null null null
        }

        //初始化一个String类型的数组
          //1.静态初始化
        String[] str1 = {"abc","bcd","cde"};
        for (int i = 0; i < str1.length; i++) {
            System.out.println(str1[i]);
        }
        //2.动态初始化
        String[] str2 = new String[3];
        for (int i = 0; i < str2.length; i++) {
            System.out.println(str2[i]);
        }

    }

}

동적 저장 메모리 맵

메서드의 매개변수는 배열입니다

배열이 전달되면 메서드도 이를 받습니다. 배열 형태로, 이 배열은 정적일 수도 있고 동적으로 생성될 수도 있으며

메소드를 정적으로 작성하여 새 객체 없이
를 호출할 수 있습니다.

예제 1:

package com.bjpowernode.javase.array;

public class ArrayTest02 {
    //也可以采用C++的风格,写成String args[]
    public static void main(String args[]) {
        System.out.println("HelloWorld");
        // 1.方法的参数传数组---静态初始化方式
        int[] a = {1,2,3,4,5};
        printArray(a);
        // 2.方法的参数传数组---动态初始化方式
        int[] arr = new int[5];
        printArray(arr);
        //   直接一步完成
        printArray(new int[3]);

    }
    //静态方法进行打印
    public static void printArray(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

}
예제 2: (마스터)

(1) 정적 배열을 직접 전달하는 경우의 특수한 경우, 구문은 다음과 같이 작성해야 합니다!

(2) 먼저 예를 살펴보겠습니다.

int[] arr = {1,2,3}

; 배열의 매개변수를 전달할 때 일반적으로 배열 이름 arr을 전달합니다. 예:

printArray( arr); 하지만 또 다른 방법은 이를 전달하고 배열 이름 arr의 나머지 구성 요소를 제거하는 것입니다: int[]{1,2,3}. 그러나 새 키워드를 추가합니다(예: printArray(new int[). ]{1, 2,3})

;

package com.bjpowernode.javase.array;

public class ArrayTest03 {
    public static void main(String[] args) {
     //----------1.动态初始化一位数组(两种传参方式)
        //第一种传参方式
        int[] a1 = new int[5];//默认是5个0
        printArray(a1);
        System.out.println("-------------");
        //第二种传参方式
        printArray(new int[3]);
        System.out.println("-------------");
     //----------2.静态初始化一位数组(两种传参方式)
        //第一种传参方式
        int[] a2 = {1,2,3};
        printArray(a2);
        System.out.println("-------------");
        //第二种传参方式----直接传递一个静态数组
        printArray(new int[]{4,5,6});

    }
    //调用的静态方法----静态方法比较方便,不需要new对象
    public static void printArray(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

메인 메소드의 문자열 배열

(1) main(String[] args) 분석: 메인 메소드 호출을 담당하는 사람(JVM) )

JVM이 main을 호출합니다. 메소드를 호출하면 길이가 0인 문자열 배열이 자동으로 전달됩니다.


예제 1:

package com.bjpowernode.javase.array;

public class ArrayTest04 {
    // 这个方法程序员负责写出来,JVM负责调用。JVM调用的时候一定会传一个String数组过来。
    public static void main(String[] args) {
        // JVM默认传递过来的这个数组对象的长度?默认是0
        // 通过测试得出:args不是null。
        System.out.println("JVM给传递过来的String数组参数,它这个数组的长度是?"
        + args.length); //0

        // 以下这一行代码表示的含义:数组对象创建了,但是数组中没有任何数据。就等价于:
        String[] strs = new String[0]; //动态的方式
        //String[] strs = {}; // 静态初始化数组,里面没东西。
        printLength(strs); //调用printLength静态方法

/*
     既然传过来的“String[] args”数组里什么都没有;那么这个数组什么时候里面会有值呢?
     其实这个数组是留给用户的,用户可以在控制台上输入参数,这个参数自动会被转换为“String[] args”
     例如这样运行程序:java ArrayTest04 abc def xyz;相当于在编译时进行传参
     那么这个时候JVM会自动将“abc def xyz”通过空格的方式进行分离,分离完成之后,自动放到“String[] args”数组当中。
     所以main方法上面的String[] args数组主要是用来接收用户输入参数的。
     把abc def xyz 转换成字符串数组:{"abc","def","xyz"}
*/
        // 遍历数组
        for (int i = 0; i < args.length; i++) {
            System.out.println(args[i]);
        }
        //既然是编译时进行传参,对于编译运行一体的IDEA怎么使用呢?
        //Run--->EditConfiguration--->Program Arguments里面进行传参,然后在从后重新运行

    }

    public static void printLength(String[] args){
        System.out.println(args.length); // 0
    }
}
예제 2:

(1) 메인 메소드 위에 있는 "String[] args"의 용도는 무엇입니까?

로그인 시스템을 시뮬레이션하는 데 사용할 수 있습니다

! 다음 흥미로운 예를 살펴보십시오.

package com.bjpowernode.javase.array;
/*
   模拟一个系统,假设这个系统要使用,必须输入用户名和密码。
*/
public class ArrayTest05 {
    public static void main(String[] args) {
        //先判断长度,是不是两个字符串长度,不是2直接终止程序
        if(args.length != 2){
            System.out.println("请输入用户名和密码");
            return;
        }

        //取出用户名和密码
        String username = args[0];
        String password = args[1];
        // 假设用户名是admin,密码是123的时候表示登录成功。其它一律失败。
        // 判断两个字符串是否相等,需要使用equals方法。
        // if(username.equals("admin") && password.equals("123")){ //这样有可能空指针异常
        // 下面这种编写方式,也可以避免空该指针异常!
        if("admin".equals(username) && "123".equals(password)){ 
            System.out.println("恭喜你,登录成功");
            System.out.println("您可以继续使用该系统");
        }else{
            System.out.println("账户或密码错误,请重新输入");
        }
    }
}

참조 데이터 유형을 배열에 저장(핵심 사항)

(1) 1차원 배열의 깊이: 배열에 저장된 유형은 다음과 같습니다.

참조 데이터 유형
; 배열의 경우 실제로 Java 개체의 "메모리 주소"만 저장할 수 있습니다.

배열에 저장된 각 요소는 "참조"입니다 . 다음 예시 질문은 이해에 중점을 두고 있습니다! (2)배열은 배열의 요소가 동일한 유형이어야 하지만

하위 유형도 저장할 수 있습니다

!

package com.bjpowernode.javase.array;
public class ArrayTest06 {
    public static void main(String[] args) {
        //1.静态创建一个Animal类型的数组
        Animal a1 = new Animal();
        Animal a2 = new Animal();
        Animal[] animals = {a1,a2};

        //对Animal数组进行遍历
        for (int i = 0; i < animals.length; i++) {
            //方法1
            /*Animal a = animals[i];
            a.move();*/
            //方法2
            animals[i].move();
        }

        //2.动态初始化一个长度为2的animal类型的数组
        Animal[] ans = new Animal[2];
        ans[0] = new Animal();
        //ans[1] = new Product(); //err,Product和Animals没有任何关系
        //Animal数组中只能存放Animal类型,不能存放Product类型

        //3.Animal数组中可以存放Cat类型的数据,因为Cat是Animal一个子类
       ans[1] = new Cat();
        for (int j = 0; j < ans.length; j++) {
            ans[j].move();
        }

        //4.创建一个Animal类型的数据,数组当中存储Cat和Bird
          //4.1静态创建
        Cat cat = new Cat();
        Bird bird = new Bird();
        Animal[] anim = {cat,bird};
        for (int i = 0; i < anim.length; i++) {
            //直接调用子类和父类都有的move()方法
            //anim[i].move();
            
            //这里想要调用子类Bird里面特有的方法,需要向下转型
            if(anim[i] instanceof Bird){
                Bird b = (Bird)anim[i]; //向下转型
                b.move();
                b.sing(); //调用子类特有的方法
            }else{
                anim[i].move();
            }

        }


    }
}
//动物类
class Animal{
    public void move(){
        System.out.println("Animals move.....");
    }
}
//商品类
class Product{

}

//有一个猫类继承动物类
class Cat extends Animal{
    public void move(){
        System.out.println("Cat move.....");
    }
}

//有一个鸟类继承动物类
class Bird extends Animal{
    public void move(){
        System.out.println("Bird move.....");
    }

    //鸟特有的方法
    public void sing(){
        System.out.println("鸟儿在歌唱!");
    }
}
배열 확장 및 복사

Java 개발에서 배열 길이가 불변으로 결정되면 배열이 가득 차 확장이 필요한 경우 어떻게 해야 하나요?

(1) Java에서
배열의 확장은 다음과 같습니다.

먼저 대용량 배열을 만든 다음 소용량 배열의 요소를 하나씩 대용량 배열에 복사하면 소용량이 해제됩니다.
(2) 결론: 어레이 확장 효율이 낮다. 복사 문제가 포함되어 있기 때문입니다. 따라서 향후 개발에 주의하시기 바랍니다. 배열을 가능한 한 적게 복사하십시오. 배열 객체를 생성할 때 다음과 같은 적절한 길이를 추정할 수 있습니다. 이렇게 하면 배열 확장 횟수를 줄일 수 있습니다. 효율성을 향상시킵니다.
(3)복사하려면 System.arraycopy를 사용하세요

, 총 5개의 매개변수

System.arraycopy(복사할 소스 배열, 첨자, 대상 배열, 첨자, 숫자)

package com.bjpowernode.javase.array;
public class ArrayTest07 {
    public static void main(String[] args) {
        //java中的数组是怎样拷贝的呢?System.arraycopy(5个参数)
        //System.arraycopy(源,下标,目的地,下标,个数)

        //拷贝源---把3、5、7拷贝过去
        int[] src = {1,3,5,7,9};
        //拷贝目的地---拷贝到下标为5的地方
        int[] dest = new int[20];
        //调用拷贝函数
        System.arraycopy(src,1,dest,5,3);
        //打印验证
        for (int i = 0; i < dest.length; i++) {
            System.out.println(dest[i]+" ");
        }

        //拷贝引用数据类型
        String[] str = {"hello","world"};
        String[] strs = new String[10];
        System.arraycopy(str,0,strs,3,2);
        for (int i = 0; i < strs.length; i++) {
            System.out.println(strs[i]);
        }
        System.out.println("--------------");
        
        //采用动态开辟的时候拷贝的是地址
        Object[] objs = {new Object(),new Object(),new Object()};
        Object[] objects = new Object[5];
        System.arraycopy(objs,0,objects,0,3);
        for (int i = 0; i < objects.length; i++) {
            System.out.println(objects[i]);

        }

    }
}

内存图

推荐学习:《java视频教程

위 내용은 Java에서 배열의 정의와 사용에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제