자바 개발자 일기 5일차

Shy·2024년 1월 3일

아이티윌

목록 보기
5/22

패키지(Package)

패키지(package)는 자바에서 관련된 클래스와 인터페이스를 그룹화하는 방법이다. 이를 사용하면 코드를 더 잘 조직할 수 있고, 이름 충돌을 방지할 수 있다. 예를 들어, 두 개의 다른 개발자가 'Employee'라는 이름의 클래스를 만들 경우, 각자의 클래스를 서로 다른 패키지에 넣어서 이름 충돌을 피할 수 있다.

패키지는 물리적으로는 디렉토리 구조로 표현된다. 예를 들어, com.mycompany.myapp라는 패키지는 com/mycompany/myapp라는 디렉토리 구조로 파일 시스템에 저장된다. 자바 소스 파일의 맨 위에 package 키워드를 사용하여 이 파일이 어떤 패키지에 속하는지 선언한다.

패키지의 장점

  • 네임스페이스 관리: 동일한 이름의 클래스나 인터페이스가 서로 다른 패키지에 있을 수 있으므로, 이름 충돌 문제를 피할 수 있다.
  • 접근 제한: 패키지 내의 클래스들은 패키지-프라이빗 멤버를 통해 서로 쉽게 접근할 수 있다. 이는 캡슐화와 보안을 향상시킨다.
  • 유지보수성: 관련된 클래스와 인터페이스를 그룹화함으로써 코드의 구조를 더 명확하게 하고, 유지보수를 용이하게 한다.

패키지 사용 예시

package com.mycompany.myapp;

public class MyClass {
    // 클래스 내용
}

이 예시에서 MyClass는 com.mycompany.myapp 패키지에 속한다. 이 패키지 내의 다른 클래스들은 MyClass에 쉽게 접근할 수 있으며, 다른 패키지의 클래스들은 import 문을 사용하여 MyClass를 사용할 수 있다.

/*
 * package 선언문 : java파일의 맨 첫줄에 위치하며, 한 번만 작성한다.
 * 자바(class)파일의 위치를 나타냄
 * 일반적으로 회사의 도메인명 반대로 사용
 * 작성예) com.naver.project, com.itwill.mystudy
 */

package edu.class1.basic;

// import 선언문 : 선택항목이지만 일반적으로 사용
// (java.lang 패키지 이외의 패키지에 있는 타입 사용시 import사용)
// import.util.*: 자바 유틸에 있는 모든 항목을 가져온다. 보통은 명시적으로 가져오는 것을 권장한다.
import java.util.Scanner;

public class Ex01_package_import_class {

	public static void main(String[] args) {
		// java.util.Scanner scan = new java.util.Scanner(System.in);
		Scanner scan = new Scanner(System.in);
		System.out.print(">> 인사말 : ");
		String hello = scan.nextLine();
		System.out.println("인사말 출력 : " + hello);

	}

}
  • 패키지 선언 (package edu.class1.basic;):
    • 이 선언은 해당 자바 파일이 edu.class1.basic이라는 패키지에 속함을 나타낸다.
    • 패키지 선언은 파일의 맨 위에 위치하며, 한 파일에 한 번만 작성된다.
    • 패키지는 일반적으로 회사의 도메인 이름을 역순으로 사용하는데, 예를 들어 com.naver.projectcom.itwill.mystudy와 같은 형식을 취한다.
    • 여기서 edu.class1.basic는 교육적 목적으로 설정된 예시 패키지 이름이다.
  • import 선언 (import java.util.Scanner;):
    • 이 import 문은 java.util 패키지에 있는 Scanner 클래스를 현재 클래스 파일에서 사용할 수 있게 한다.
    • import 문은 선택적으로 사용되며, java.lang 패키지 외의 다른 패키지에 있는 타입(클래스, 인터페이스 등)을 사용할 때 필요하다.
    • import java.util.*;와 같이 사용하면 java.util 패키지에 있는 모든 클래스와 인터페이스를 임포트하지만, 이 예제에서는 Scanner 클래스만 명시적으로 임포트한다. 이는 일반적으로 권장되는 방식이다.
      클래스 선언 (public class Ex01_package_import_class):
    • Ex01_package_import_class라는 이름의 공개 클래스를 선언한다.
    • 이 클래스는 main 메소드를 포함하고 있어, 자바 애플리케이션의 진입점(entry point)이 된다.
  • main 메소드 내의 코드:
    • Scanner 객체를 생성하여 사용자로부터 입력을 받습니다. 이 때 Scanner 클래스는 위에서 import한 java.util.Scanner를 참조한다.
    • 사용자로부터 입력 받은 문자열을 hello 변수에 저장한 후, 이를 출력한다.

클래스

자바에서 클래스(class)는 객체를 생성하기 위한 템플릿이나 블루프린트로 생각할 수 있다. 클래스는 객체의 상태를 정의하는 필드(변수)와 행동을 정의하는 메소드(함수)로 구성된다. 객체 지향 프로그래밍의 핵심 개념 중 하나로, 데이터와 그 데이터를 조작하는 메소드를 하나의 단위로 묶는다.

클래스를 사용하는 주요 목적은 데이터 캡슐화, 코드 재사용, 그리고 모듈식 프로그래밍을 통한 유지보수성 향상이다. 클래스를 통해 같은 종류의 상태(속성)와 행동(메소드)을 갖는 여러 객체를 생성할 수 있다.

클래스의 기본 구조

  • 필드(Field): 클래스에 포함된 변수로, 객체의 상태를 나타낸다. 예를 들어, 'Dog' 클래스에는 'breed', 'size', 'age'와 같은 필드가 있을 수 있다.
  • 메소드(Method): 클래스에서 객체의 행동을 정의하는 함수. 예를 들어, 'Dog' 클래스에는 'bark()', 'eat()', 'sleep()'과 같은 메소드가 있을 수 있다.
  • 생성자(Constructor): 클래스의 새로운 인스턴스를 생성할 때 호출되는 특별한 메소드. 생성자는 클래스 이름과 동일하며, 객체 초기화에 사용된다.

클래스의 예시

public class Dog {
    // 필드
    String breed;
    int age;
    String color;

    // 생성자
    Dog(String breed, int age, String color) {
        this.breed = breed;
        this.age = age;
        this.color = color;
    }

    // 메소드
    void bark() {
        System.out.println("멍멍!");
    }

    void eat() {
        // 먹는 행동 구현
    }

    void sleep() {
        // 자는 행동 구현
    }
}

이 예시에서 'Dog' 클래스는 'breed', 'age', 'color'라는 필드와 'bark()', 'eat()', 'sleep()'라는 메소드를 갖고 있다. 또한, 'Dog' 객체를 초기화하는 생성자도 정의되어 있다. 클래스를 정의한 후에는 이 클래스의 인스턴스(객체)를 생성하여 사용할 수 있다.

Dog myDog = new Dog("진돗개", 5, "갈색");
myDog.bark();

이 코드는 'Dog' 클래스의 인스턴스를 생성하고, 'bark' 메소드를 호출한다. 클래스와 객체는 자바 프로그래밍에서 중요한 요소이며, 데이터와 기능을 함께 묶어서 코드의 재사용성과 관리 효율성을 높인다.

예제

package edu.class1.basic;

// 클래스 선언
public class Ex02_class {
	// ======변수 선언 영역======
	// 필드변수(인스턴스 변수, 멤버변수, 속성-property, 전역변수) 선
	int num = 111;
	
	// 클래스 변수, 스테틱(static)변수, 인스턴스(객체) 공통변
	static int staticNum = 222;
	
	// ======생성자 선언 영역======
	public Ex02_class() { } // 기본생성자(default constructor)생략 가능
	
	// ======메소드 선언 영역======
	// main 메소드(메서드)
	public static void main(String[] args) {
		// 로컬변수(지역변수)
		int num1 = 100;
		int num2 = 200;
		int result = num1 + num2;
		System.out.println("result: " + result);
		
		int result2 = add(num1, num2); //호출(실행) 한다.
		System.out.println("add()결과 result2: " + result2);

	}
	
	public static int add(int a, int b) {
		return a + b;
	}

}

메소드(Method)

자바에서 메소드(method)는 특정 작업을 수행하는 코드 블록이다. 메소드는 특정한 작업을 수행하도록 설계되어 있으며, 필요할 때마다 호출되어 사용된다. 메소드는 객체 지향 프로그래밍의 중요한 요소로, 클래스의 동작이나 행동을 정의한다.

메소드의 기본구조

접근제어자 반환타입 메소드명(매개변수목록) {
    // 메소드 바디
    // 수행할 코드
    return 반환값;  // 반환타입이 void가 아닐 경우
}
  • 접근제어자(Access Modifier): 메소드에 접근할 수 있는 범위를 지정한다 (public, private, protected, 없음 등).
  • 반환타입(Return Type): 메소드가 처리한 결과를 반환하는 데이터의 타입이다. 아무것도 반환하지 않을 경우 void로 지정한다.
  • 메소드명(Method Name): 메소드를 호출하기 위한 이름입니다. 자바의 네이밍 컨벤션에 따라 작성한다.
  • 매개변수목록(Parameter List): 메소드에 전달되는 인자(입력값)의 목록이다. 인자가 없을 경우 비워둔다.
  • 메소드 바디(Method Body): 메소드가 호출될 때 실행될 코드 블록이다.

메소드의 특징

  • 재사용성: 한 번 정의된 메소드는 여러 곳에서 호출되어 사용될 수 있다.
  • 모듈성: 메소드를 사용하면 복잡한 코드를 작은 단위로 나누어 관리할 수 있다.
  • 유지보수 용이: 프로그램의 각 부분을 메소드로 분리하면, 수정이 필요할 때 해당 메소드만 수정하면 된다.

메소드의 예시

public class Calculator {

    // 두 수의 합을 계산하는 메소드
    public int add(int num1, int num2) {
        return num1 + num2;
    }

    // 두 수의 차를 계산하는 메소드
    public int subtract(int num1, int num2) {
        return num1 - num2;
    }
}

public class Main {
    public static void main(String[] args) {
        Calculator calc = new Calculator();
        int sum = calc.add(5, 3);
        int diff = calc.subtract(5, 3);

        System.out.println("합: " + sum);
        System.out.println("차: " + diff);
    }
}

이 예제에서 Calculator 클래스는 add와 subtract라는 두 메소드를 가지고 있다. main 메소드에서는 Calculator 객체를 생성하고 이 객체의 메소드들을 호출하여 두 수의 합과 차를 계산한다. 메소드를 사용함으로써 코드가 간결하고 읽기 쉬워지며, 각 계산 로직을 재사용할 수 있다.

메소드 예시2

package edu.class1.basic;

/*
 * ==== 메소드(method) 4가지 형태 ====
 * 리턴(return)값 유무와 파라미터(parameter)유무 기준
 * 1. 리턴값 없음, 전달받는 파라미터 없음
 * 	void 메소드명() {}
 * 2. 리턴값 없음, 전달받는 파라미터 있음
 * 	void 메소드명(파라미터타입 변수명, ...) {}
 * 3. 리턴값 있음, 전달받는 파라미터 없음
 * 	리턴타입 메소드명 () {}
 * 4. 리턴값 있음, 전달받는 파라미터 있음
 * 	리턴타입 메소드명(파라미터타입 변수명, ...) {}
 */

public class Ex03_method {

	public static void main(String[] args) {
		int num1 = 500;
		int num2 = 200;
		
		int sum = add(num1, num2); // 메소드 호출(실행)
		System.out.println("sum : " + sum);
		
		//Cannot make a static reference to the non-static method sub(int, int) from the type Ex03_method
		//sub(num1, num2);
		//static영역에서 non-static 영역 접근시 객체(인스턴스)를 통해서 사용해야 한다.
		//인스턴스(객체)를 사용하면 static, non-static변수, 메소 모두 사용
		Ex03_method ex03 = new Ex03_method();
		System.out.println("sub : " + ex03.sub(num1, num2));
		System.out.println("multiple : " + ex03.multiple(num1, num2));
		System.out.println("div : " + ex03.div(num1, num2));
	}

	// 메소드 선언(static)
	static int add(int a, int b) {
		return a + b;
	}
	
	int sub(int a, int b) {
		return a - b;
	}
	
	int multiple(int a, int b) {
		return a * b;
	}
	
	int div(int a, int b) {
		return a / b;
	}
	
	// --------------------------------
	void method() {
		System.out.println("파라미터 X, return 값 X");
	}
	
	void method2(String param) {
		System.out.println("파라미터 O, return 값 X");
	}
	
	String method3() {
		System.out.println("파라미터 X, return 값 O");
		return("파라미터 X, return 값 O");
	}
	
	String method4(String param) {
		System.out.println("파라미터 O, return 값 O");
		return("파라미터 O, return 값 O");
	}
}

static

static 키워드의 사용은 클래스 레벨의 변수나 메소드에 적용된다. 이는 해당 멤버가 클래스의 인스턴스(객체)에 속하는 것이 아니라, 클래스 자체에 속한다는 것을 의미한다. static 멤버는 클래스의 모든 인스턴스 간에 공유되며, 객체를 생성하지 않고도 접근할 수 있다.

'static'변수 사용

정적 변수(Static Variable)

클래스의 모든 인스턴스에서 공유되는 변수이다. 모든 인스턴스에서 이 변수의 값은 동일하며, 한 인스턴스에서 값을 변경하면 다른 모든 인스턴스에도 영향을 준다.

public class MyClass {
    static int staticVariable; // 정적 변수 선언

    public void increment() {
        staticVariable++; // 정적 변수 값 증가
    }
}

이 예제에서 staticVariable은 MyClass의 모든 인스턴스에 공통된 값으로 존재한다.

'static' 메소드 사용

정적 메소드(Static Method)

정적 메소드는 인스턴스 변수나 메소드를 사용하지 않고, 클래스 레벨에서 작동한다. 이들은 클래스 이름을 통해 직접 호출될 수 있다.

public class UtilityClass {
    public static int add(int a, int b) {
        return a + b; // 정적 메소드
    }
}

// 메소드 사용
int sum = UtilityClass.add(5, 10); // 객체 생성 없이 호출

이 예제에서 add 메소드는 UtilityClass의 인스턴스를 생성하지 않고도 호출할 수 있다.

static 사용 시 주의사항

  • 정적 메소드는 인스턴스 변수나 메소드에 직접 접근할 수 없다. 이들은 오직 정적 변수나 다른 정적 메소드에만 접근할 수 있다.
  • 정적 변수는 프로그램 실행 중 항상 메모리에 존재하므로, 과도한 사용은 메모리 관리 측면에서 비효율적일 수 있다.
  • 정적 메소드는 오버라이딩될 수 없다. 즉, 상속받은 클래스에서 동일한 시그니처의 메소드를 정의하더라도, 정적 메소드는 다형성을 지원하지 않는다.

static 키워드는 주로 유틸리티 함수나 상수, 싱글톤 디자인 패턴 등 특정 상황에서 유용하게 사용된다. 클래스의 특정 상태나 객체의 고유한 상태를 나타내는 데에는 적합하지 않으므로, 적절한 상황에서 신중하게 사용해야 한다.

정적 메소드는 오버라이딩될 수 없다?

정적 메소드와 다형성

  1. 다형성(Polymorphism): 다형성은 같은 이름의 메소드가 여러 클래스에서 다른 동작을 할 수 있도록 하는 객체 지향 프로그래밍의 특성이다. 이는 주로 메소드 오버라이딩(Overriding)을 통해 구현된다.
  2. 메소드 오버라이딩(Method Overriding): 서브클래스가 슈퍼클래스에서 상속받은 메소드를 재정의하는 것을 말한다. 오버라이딩된 메소드는 객체의 타입에 따라 다른 동작을 할 수 있다.

정적 메소드와 오버라이딩

정적 메소드는 클래스 레벨에 존재하므로, 인스턴스 타입에 따라 그 동작이 바뀌지 않는다. 이는 정적 메소드가 다형성을 지원하지 않는다는 것을 의미한다.

  1. 정적 메소드는 숨겨질 수 있지만, 오버라이딩되지 않는다(Hiding, not Overriding): 서브클래스에서 동일한 시그니처를 가진 정적 메소드를 정의하면, 슈퍼클래스의 정적 메소드를 '숨긴다'(hiding). 이는 오버라이딩과 다르다. 숨겨진 메소드는 서브클래스의 정적 메소드로, 슈퍼클래스의 정적 메소드와 별개로 존재한다.
  2. 정적 메소드 호출은 클래스 타입에 따라 결정됩니다: 정적 메소드의 호출은 인스턴스의 타입이 아닌, 참조 변수의 타입에 의해 결정된다. 따라서 정적 메소드는 런타임 다형성을 제공하지 않는다.

예시

class Superclass {
    static void print() {
        System.out.println("슈퍼클래스의 정적 메소드");
    }
}

class Subclass extends Superclass {
    static void print() {
        System.out.println("서브클래스의 정적 메소드");
    }
}

public class Test {
    public static void main(String[] args) {
        Superclass obj = new Subclass();
        obj.print(); // 슈퍼클래스의 print() 호출
    }
}

이 예제에서 Subclass는 Superclass의 print 메소드를 '숨긴다'. 그러나 main 메소드에서 obj.print()를 호출할 때 Superclass의 print 메소드가 호출된다. 이는 정적 메소드가 클래스 타입에 따라 호출되고, 런타임에 객체의 타입에 따라 다르게 동작하지 않기 때문이다.

결론적으로, 정적 메소드는 상속받은 클래스에서 같은 시그니처로 메소드를 정의하더라도 오버라이딩되지 않으며, 이는 정적 메소드가 다형성을 지원하지 않는 중요한 이유 중 하나이다.

실습예제 1

Car.java

package edu.class2.car;

/*
 * 자동차 클래스
 * 	속성: 차량명, 모델명, 차량색상
 * 	기능: 가고, 서고, 뒤로가고, 차량정보 확
 */

public class Car {
	// 필드변수(속성)
	String name; // 차량
	String model; // 모델명
	String color; // 차량색
	
	// final 제한자 : 변수에 값이 할당되면 더이상 변경할 수 없다.
	// final 붙은 변수 : 상수화된 변수(상수-constant)
	final int CAR_LENGTH = 350;
	final int CAR_WIDTH = 200;
	
	boolean hasAirbag;
	
	// 생성자 : 리턴타입 없음, 생성자 명칭은 클래스명 사용
	// 클래스명() {} - 기본생성자
	// 클래스명(매개변수, ....) {}
	// 생성자 작성이 안되면 기본생성자를 컴파일러가 만들어준다.
	public Car() {
		name = "마이카";
	}
	
	public Car(String n, String m, String c) {
		name = n;
		model = m;
		color = c;
	} 
	
	// 메소드(기능, 동작, 함수)
	void run() {
		System.out.println(">>앞으로 이동");
	}
	
	void run(int speed) {
		System.out.println(">>앞으로 " + speed + "km속도로 이동");
	}
	
	void stop() {
		System.out.println(">>멈추기");
	}
	
	void back( ) {
		System.out.println(">>뒤로가기");
	}
	
	// 자동차 속성값 확인 메소드
	void dispData() {
		System.out.println("--- 자동차 정보 ---");
		System.out.println("자동차이름 : " + name);
		System.out.println("자동차모델 : " + model);
		System.out.println("자동차색상 : " + color);
		System.out.println("차량길이 : " + CAR_LENGTH);
		System.out.println("차량폭 : " + CAR_LENGTH);
		System.out.println("에어백유무 : " + hasAirbag);
	}
	

	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}

CarMain.java

package edu.class2.car;

public class CarMain {

	public static void main(String[] args) {
		// Car 클래스를 이용해서 Car 타입의 객체(인스턴스) 생성
		Car car1 = new Car();
		car1.color = "검정";
		// car1.CAR_LENGTH = 220; 파이널 변수는 변경 불가, 상수화된 변수 값은 변경이 불가하다.
		
		System.out.println("자동차이름 : " + car1.name);
		System.out.println("모델명 : " + car1.model);
		System.out.println("색상 : " + car1.color);
		System.out.println("차량길이 : " + car1.CAR_LENGTH);
		System.out.println("차량폭 : " + car1.CAR_LENGTH);
		System.out.println("에어백유무 : " + car1.hasAirbag);
		System.out.println("--------------------");
		car1.name = "처음 가져본 차";
		car1.hasAirbag = true;
		System.out.println("자동차이름 : " + car1.name);
		System.out.println("에어백유무 : " + car1.hasAirbag);
		
		System.out.println("---- 기능테스트 ----");
		car1.run();
		car1.back();
		car1.stop();
		
		System.out.println("-------car2 사용	-------");
		Car car2 = new Car("패밀리카", "제네시스", "검정");
		car2.dispData();
		car2.run(80);
		
	}

}

실습예제2

Phone.java

package com.mystudy.phone;

public class Phone {
	String name;
	String type;
	int hsize;
	int vsize;
	boolean hasLCD;
	
	public Phone () {
		name = "S21";
		type = "Galaxy";
		hsize = 20;
		vsize = 10;
		hasLCD = false;
	}
	
	public Phone (String model, String t) {
		this.name = model; // this 현재객체 (인스턴스)
		this.type = t;
	}
	
	public Phone (String model, String t, boolean LCD) {
		this.name = model;
		this.type = t;
		this.hasLCD = LCD;
	}
	
	// void: 리턴값이 없을 때 사
	void call() {
		System.out.println("전화걸기");
	}
	
	void receiveCall () {
		System.out.println("전화받기");
	}
	
	void sendSms (String message) {
		System.out.println("[메세지전송] " + message);
	}
	
	String receiveSms (String message) {
		System.out.println("[메세지수신] " + message);
		return (message);
	}
	
	void view() {
		System.out.println("--- 핸드폰 정보 ---");
		System.out.println("핸드폰이름 : " + name);
		System.out.println("핸드폰타입 : " + type);
		System.out.println("핸드폰가로크기 : " + hsize);
		System.out.println("핸드폰세로크기 : " + vsize);
		System.out.println("핸드폰LCD유무 : " + hasLCD);
	}


}

PhoneMain.java

package com.mystudy.phone;

public class PhoneMain {

	public static void main(String[] args) {
		Phone phone1 = new Phone();
		Phone phone2 = new Phone("15 Pro max", "IPhone");
		Phone phone3 = new Phone("S22 Ultra", "Galaxy", false);
		
		phone1.view();
		phone2.view();
		phone3.view();
		
		phone1.call();
		phone1.receiveCall();
		phone1.sendSms("안녕하세요.");
		phone1.receiveSms("hello world");
		
//		--- 핸드폰 정보 ---
//		핸드폰이름 : S21
//		핸드폰타입 : Galaxy
//		핸드폰가로크기 : 20
//		핸드폰세로크기 : 10
//		핸드폰LCD유무 : false
//		--- 핸드폰 정보 ---
//		핸드폰이름 : 15 Pro max
//		핸드폰타입 : IPhone
//		핸드폰가로크기 : 0
//		핸드폰세로크기 : 0
//		핸드폰LCD유무 : false
//		--- 핸드폰 정보 ---
//		핸드폰이름 : S22 Ultra
//		핸드폰타입 : Galaxy
//		핸드폰가로크기 : 0
//		핸드폰세로크기 : 0
//		핸드폰LCD유무 : false
//		전화걸기
//		전화받기
//		[메세지전송] 안녕하세요.
//		[메세지수신] hello world

	}

}

Array

배열(Array)은 자바에서 일련의 동일한 타입의 요소들을 하나의 연속된 메모리 블록에 저장하는 데이터 구조이다. 배열은 고정된 크기를 가지며, 배열 내의 각 요소는 인덱스를 사용하여 접근할 수 있다. 배열은 다양한 데이터 타입(기본형 또는 객체형)의 요소들을 저장할 수 있다.

배열의 기본적인 특징

  1. 동일한 타입의 데이터 저장: 배열은 같은 타입의 여러 데이터를 저장한다. 예를 들어, int 배열은 여러 개의 int 타입 값을 저장할 수 있다.
  2. 고정된 크기: 배열은 생성 시 정해진 크기를 가지며, 이 크기는 변경할 수 없다.
  3. 인덱스 접근: 배열의 각 요소는 인덱스를 통해 접근할 수 있다. 인덱스는 0부터 시작하여 배열 길이의 -1까지 이다.
  4. 연속된 메모리 할당: 배열의 요소들은 메모리 상에서 연속적으로 할당된다.

배열의 제한

  • 한 번 생성된 배열의 크기는 변경할 수 없다. 더 많은 요소를 저장해야 하는 경우 새 배열을 생성하고 요소를 복사해야 한다.
  • 배열은 기본적으로 정적인 구조를 가지고 있어 동적인 데이터 저장에는 제한적이다. 이런 경우에는 ArrayList와 같은 동적인 컬렉션을 사용하는 것이 더 유연할 수 있다.

배열의 선언 및 초기화

선언

배열을 선언할 때는 요소의 타입과 배열 변수의 이름을 지정한다.

Copy code
int[] numbers; // int 타입의 배열 선언
String[] names; // String 타입의 배열 선언

생성

new 키워드를 사용하여 배열을 생성하고, 배열의 크기를 지정한다.

numbers = new int[10]; // 10개의 int 타입 요소를 가진 배열 생성

초기화

배열을 생성할 때 요소에 초기 값을 할당할 수 있다.

int[] numbers = {1, 2, 3, 4, 5}; // 초기 값이 할당된 int 배열 생성

배열의 사용

배열의 각 요소에 접근하려면 인덱스를 사용합니다. 인덱스는 대괄호 [] 안에 지정한다.

int firstNumber = numbers[0]; // 첫 번째 요소에 접근
numbers[3] = 10; // 네 번째 요소에 10을 할당

배열의 길이를 알아내려면 length 속성을 사용한다.

int arrayLength = numbers.length; // 배열의 길이

예제코드

package com.mystudy.array1;

import java.util.Arrays;

public class Ex01_array1 {

	public static void main(String[] args) {
		// 배열(array) : 동일한 데이터 타입들의 연속된 저장 공간
		// 배열의 선언 : 자료형[] 변수명
		// 변수에 값 저장 : 배열변수명[인덱스번호] = 값;
		/* 배열의 선언 및 생성
		 * 1. 자료형 [] 변수명 = new 자료형[갯수];
		 *    자료형 변수명 [] = new 자료형[갯수];
		 * 2. 자료형 [] 변수명 = new 자료형[] {값1, 값2, 값3, ..., 값n};
		 * 3. 자료형 [] 변수명 = {값1, 값2, 값3, ..., 값n}; // n개 저장공간 생성 +  초기값 성
		 ------------------------------*/
		// 1. 자료형[] 변수명 = new 자료형[갯수];
		int[] arr = new int[5]; // int 타입 값 5개를 저장할 수 있는 배열 arr 선언
		System.out.println("arr : " + arr);
		System.out.println("arr[0] : " + arr[0]); // 0
		arr[0] = 10;
		System.out.println("arr[0] : " + arr[0]); // 10
		System.out.println("arr[1] : " + arr[1]); // 0
		arr[1] = 11;
		System.out.println("arr[1] : " + arr[1]); // 11
		arr[2] = 12;
		arr[3] = 13;
		arr[4] = 14; // 마지막 위치(length - 1)
		// arr[5] 범위초과 에러
		
		System.out.println("-----------------------------");
		// 2. 자료형 [] 변수명 = new 자료형[] {값1, 값2, 값3, ..., 값n};
		int sum = 0;
		for (int i = 0; i <= 4; i++) {
			sum = sum + arr[i];
		};
		System.out.println("sum : " + sum);
		
		System.out.println("-----------------------------");
		// 배열에 있는 데이터 화면 출력
		for (int i = 0; i <= 4; i++) {
			System.out.println("arr[" + i + "] : " + arr[i]);
		};
		
		System.out.println(arr.length);
		
		// 3. 자료형 [] 변수명 = {값1, 값2, 값3, ..., 값n}; // n개 저장공간 생성 +  초기값 성
		System.out.println("-----------------------------");
		int[] arr3 = {10, 11, 12, 13, 14};
		for (int i = 0; i < arr3.length; i++) {
			System.out.println("arr[" + i + "] : " + arr3[i]);
		};
		
		System.out.println("=============================");
		System.out.println("==== 영어 알파벳 저장 출력(A~Z) ====");
		char[] ch = new char[26];
		System.out.println("-" + ch[0] + "-"); // default : 
		ch[0] = 'A'; // 65
		System.out.println("ch[0] : " + ch[0]);
		ch[1] = 'B'; // 66 <------------- 65 + 1
		System.out.println("ch[1] : " + ch[1]);
		ch[2] = 'B' + 1; // 67
		System.out.println("ch[2] : " + ch[2]);
		System.out.println("--------------------");
		
		ch[0] = 'A';
		ch[1] = 'A' + 1; // B
		ch[2] = 'A' + 2; // C
		ch[3] = 'A' + 3; // D
		System.out.println("ch[3] : " + ch[3]);
		System.out.println(Arrays.toString(ch));
		
		for (int i = 0; i < ch.length; i++) {
			// ch[i] = 'A' + i; // mismatch error
			ch[i] = (char)('A' + i); // int 타입 데이터 ----> char 타입으로 형변
		}
		System.out.println(Arrays.toString(ch)); // 어떤 값들이 들어가 있는지 확인
		
		// 배열에 저장된 값 출력
		for (int i = 0; i < ch.length; i++) {
			System.out.print(ch[i] + " ");
		}
		System.out.println();

	}

}

실습예제1

package com.mystudy.array1;

public class Ex02_array2 {
	
	public static void main(String[] args) {
		// 문제1 : 1 ~ 10까지의 수를 배열에 저장(반복문사용) 하고
		//       배열 데이터 화면 출
		// 배열선언 : 1. 자료형[] 변수명 = new 자료형[갯수];
		// 출력형태 : 변수명[인겟스번호] : 값
		// nums[0] : 1
		// nums[1] : 2
		// nums[2] : 3
		// ---------------------------------------------
		int[] arr1 = new int[10];
		for (int i = 0; i < arr1.length; i++) {
			arr1[i] = i + 1;
			System.out.println("nums[" + i + "] : " + arr1[i]);
		}

		System.out.println("문제2 =====================");
		/*
		 * 문제2 : 배열(nums2)에 있는 전체 합계 구하기
		 * 저장할 숫자 : 3, 5, 7, 1, 2, 4, 6, 8, 9, 10
		 * 0. 위의 숫자가 저장된 배열을 만드시오
		 * 1. 배열에 저장된 데이터 화면 출력(반복문)
		 * 2. 배열에 저장된 데이터 합계 구하기(반복문)
		 * 3. 합계 결과 출력
		 * --------------------------------------
		 */
		int sum = 0;
		int[] arr2 = new int[] {3, 5, 7, 1, 2, 4, 6, 8, 9, 10};
		for (int i = 0; i < arr2.length; i++) {
			System.out.println("nums[" + i + "] : " + arr2[i]);
			sum = sum + arr2[i];
		}
		System.out.println("sum : " + sum);
		
		System.out.println("문제3 ======================");
		/*
		 * 문제3 : 배열값 중 짝수합, 홀수합 구하기
		 * 배열에 있는 데이터 중 짝수는 짝수끼리 합산(evenSum)
		 * 배열에 있는 데이터 중 홀수는 홀수끼리 합산(oddSum)
		 * 짝수합계, 홀수합계 출력
		 * --------------------------------------
		 */
		int evenSum = 0;
		int oddSum = 0;
		for (int i = 0; i < arr2.length; i++) {
			if (arr2[i] % 2 == 0) {
				evenSum = evenSum + arr2[i];
			} else {
				oddSum = oddSum + arr2[i];
			}
		}
		System.out.println("evenSum : " + evenSum);
		System.out.println("oddSum : " + oddSum);
		// 		출력값 -------------------
		//		nums[0] : 1
		//		nums[1] : 2
		//		nums[2] : 3
		//		nums[3] : 4
		//		nums[4] : 5
		//		nums[5] : 6
		//		nums[6] : 7
		//		nums[7] : 8
		//		nums[8] : 9
		//		nums[9] : 10
		//		문제2 =====================
		//		nums[0] : 3
		//		nums[1] : 5
		//		nums[2] : 7
		//		nums[3] : 1
		//		nums[4] : 2
		//		nums[5] : 4
		//		nums[6] : 6
		//		nums[7] : 8
		//		nums[8] : 9
		//		nums[9] : 10
		//		sum : 55
		//		문제3 ======================
		//		evenSum : 30
		//		oddSum : 25
	}

}

실습예제2

package com.mystudy.array1;

public class Ex03_array3_star {

	public static void main(String[] args) {
		/*
		 * 별찍기
		 * *
		 * **
		 * ***
		 * ****
		 * *****
		 ---------------------------- */
		// char 타입의 데이터를 5개 저장할 수 있는 배열을 만들고 별(*) 입력
		// 배열에 있는 데이터를 위치값에 맞게 읽어서 출력
		char[] arr = new char[5];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = '*';
		}
		
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j <= i; j++) {
				System.out.print(arr[j]);
				if (i == j) {
					System.out.print("\n");
				}
			}
		}
		
		char[] arr1 = new char[5];
		for (int i = 0; i < arr.length; i++) {
			arr1[i] = (char)('0' + i);
		}
		
		for (int i = 0; i < arr1.length; i++) {
			for (int j = 0; j <= i; j++) {
				System.out.print(arr1[j]);
				if (i == j) {
					System.out.print("\n");
				}
			}
		}
//		*
//		**
//		***
//		****
//		*****
//		0
//		01
//		012
//		0123
//		01234

	}

}

실습예제3: 로또

package com.mystudy.array1;

import java.util.Arrays;
import java.util.Random;

public class Ex05_array_lotto {

	public static void main(String[] args) {
		// 로또 번호 생성기
		// 1. int 타입의 숫자 45개를 저장할 수 있는 배열 선언(balls)
		// 2. 초기화 : 1~45
		// 3. 충분히 많이 섞고
		// 4. 6개 번호를 추출(앞에서 부터 6개)
		//---------------------------------------------------
		// 임의의 숫자(랜덤값)를 만들
		// Math.random(); // 0.0 ~ 0.999999.... (0.0 <= 값 < 1 double 값)
		// (int)(Math.random() * 45) : 0 ~ 44까지의 숫자 랜덤하게 생
		//---------------------------------------------------
		
		int [] balls = lotto_numbers();
		System.out.println("balls 배열 : " + Arrays.toString(balls));
		mix_balls(balls);
		System.out.println("무작위 섞은 balls 배열 : " + Arrays.toString(balls));
		int [] winning_numbers = select6(balls);
		System.out.println("당첨번호 : " + Arrays.toString(winning_numbers));
		Ascending(winning_numbers);
		System.out.println("당첨번호 정렬: " + Arrays.toString(winning_numbers));
	
	}
		
	
	static int[] lotto_numbers () {
		int [] arr = new int[45];
		for (int i = 1; i <= 45; i++) {
			arr[i-1] = i;
		}
		return arr;
	}
	
	static void balls_swap (int array[], int i, int j) {
		int temp = array[i];
		array[i] = array[j];
		array[j] = temp;
	}
	
	static void mix_balls (int array[]) {
		Random random = new Random();
		int randomNumber = random.nextInt(501) + 100000; // 100000 ~ 100500회 반복을 한다.
		for (int i = 0; i <= randomNumber; i++) {
			int ball1 = 0;
			int ball2 = 0;
			do {
				ball1 = random.nextInt(45);
				ball2 = random.nextInt(45);
			} while (ball1 == ball2);
			balls_swap(array, ball1, ball2);
			System.out.println("반복 횟수 : " + i);
			System.out.println("배열 : " + Arrays.toString(array));
			System.out.println("");
		}
	}
	
	static void Ascending (int array[]) {
		for (int i = 0; i <= array.length - 2; i++) {
			for (int j = i+1; j <= array.length - 1; j++) {
				if (array[i] > array[j]) {
				balls_swap (array, i, j);
				}
			}

		}
	}
	
	static int [] select6 (int array[]) {
		int [] selectBalls = new int [6];
		for (int i = 0; i <= 5; i++) {
			selectBalls[i] = array[i];
			}
		return selectBalls;
	}
	
	
}

실습예제4: 위치 바꾸기

package com.mystudy.array2_sort;

public class ArraySelectionSort {

	public static void main(String[] args) {
		// 	배열 숫자 데이터 정렬(오름차순: ASC)
		int[] num = {30, 20, 50, 40, 10};
		System.out.println("num : " + num);
		printData(num);
		
		System.out.println("=== 정렬시작 ===");
		// 첫번째값(인덱스 0) vs 두번째값(인덱스 1)
		Ascending(num);
		
		System.out.println("==== 이중(중첩) for문으로 변경 ====");
		// 기준값이 0~3까지
		// 배열의 마지막 데이터 인덱스 = 배열의 크기 - 1
		for (int gijun = 0; gijun < num.length - 1; gijun++) {
			for(int i = gijun + 1; i < num.length; i++) {
				if (num[gijun] > num[i]) {
					int temp = num[gijun];
					num[gijun] = num[i];
					num[i] = temp;
				}
			}
		}
		
	}
	
	static void printData(int[] num) {
		for (int i = 0; i < num.length; i++) {
			System.out.print(num[i] + " ");
		}
		System.out.println();
	}
	
	static void Ascending (int array[]) {
		for (int i = 0; i <= array.length - 2; i++) {
			for (int j = i+1; j <= array.length - 1; j++) {
				if (array[i] > array[j]) {
				array_swap (array, i, j);
				printData(array);
				}
			}

		}
	}
	static void array_swap (int array[], int i, int j) {
		int temp = array[i];
		array[i] = array[j];
		array[j] = temp;
	}
//	num : [I@15db9742
//	   30 20 50 40 10 
//	   === 정렬시작 ===
//	   20 30 50 40 10 
//	   10 30 50 40 20 
//	   10 20 50 40 30 
//	   10 20 40 50 30 
//	   10 20 30 50 40 
//	   10 20 30 40 50 
//	   ==== 이중(중첩) for문으로 변경 ====	

}
profile
신입사원...

0개의 댓글