Java,Spring

[자바 기초 문법] 문자열과 배열

뀨린 2021. 5. 13. 23:45

문자열의 선언과 생성

String 변수;  // String 타입의 변수 선언
변수 = "문자열"; // String 타입의 변수에 문자열 대입

String s1 = "안녕, 자바"; //String 타입의 변수 선언과 초기화   
String s2 = "안녕, 자바"; //String 타입의 변수 선언과 초기화 

 

문자열과 리터럴은 내부적으로 new String()을 호출해 생성한 객체이다. 

s1은 new String("안녕, 자바!")를 호출해 생성한 객체를 가리킨다. 

 

내용이 같은 문자열 리터럴이라면 더 이상 새로운 String 객체를 생성하지 않은 채 기존 리터럴을 공유한다. 따라서 s1과 s2는 동일한 String 객체를 가리킨다. 

 

문자열의 비교

public class String2Demo{
	public static void main(String[] args) {
    
    String s1 = "Hi, Java!";
    String s2 = new String("Hi, Java!");
    String s3 = "Hi, code!";
    String s4 = "Hi, Java!";
    
    //System.out.println("s1 == s2 -> " + (s1 == s2));  //output: false
    //s1 = s2;
    //System.out.println("s1 == s2 -> " + (s1 == s2));  //output: true
    
    System.out.println(s1.equals(s2)); //true
    System.out.println(s1.equals(s3)); //false
    System.out.println(s1.equals(s4)); //false
    System.out.println(s1.equalsIgnoreCase(s4)); //true
    
    System.out.println(s1.compareTo(s3));  //7
    System.out.println(s1.compareToIgnoreCase(s4)); //0
    System.out.println(s3.compareTo(s4));  //-39
    System.out.println("Hi, Java!".compareToIgnoreCase("hi,java!")); //0
    }





}

String s1 = "Hi! Java!";

String s2 = "Hi! Java!";

String s3 = new String("Hi, Java!");  👉 같은 내용이지만 가리키는 주소값이 다르다. 

String s4 = new String("Hi, Java!");

 

s1이 가르켰던 Hi, java! 👉 참조 변수가 없어서 사용할 수 없는 개체가 된다. 따라서 후에 가비지 컬렉터로 자동 수거가 된다! 

 

  • String 클래스에서 제공하는 문자열 비교 메서드

메서드: boolean equals(String s) 설명: 주어진 문자열 s와 현재 문자열을 비교한 후 true/false 반환한다. 

 

String 클래스에서 제공하는 유용한 정적 메서드

정적 메서드 설명
String format( ) 주어진 포맷에 맞춘 문자열을 반환
String join( ) 주어진 구분자와 연결한 문자열을 반환
String valueOf( ) 각종 기초 타입이나 객체를 문자열로 반환
package sec01;

public class String5Demo {
	public static void main(String[] args) {
    
    String version = String.format("%s %d", "JDK", 14);
    System.out.println(version);
    
    String fruits = String.join(", ", "apple", "banana", "cherry", "durian");
    System.out.println(fruits);
    
    String pi = String valueOf(3.14);
    System.out.println(pi);            
    }
}

<output>

 

JDK 14 

apple, banana, cherry, durian

3.14 

 

 

 배열(array)이란?

 

배열은 변수들을 연속된 집합체로 모아 놓은 것으로 동일한 이름을 사용하며 인덱스로 각 항목을 구분한다. 

import java.util.Scanner;

public class Array1Demo{
	public static void main(String[] args){
    Scanner in = new Scanner (System.in);
    int scores[] = new int[5]; //5개 입력 가능한 배열 객체 생성
    int sum = 0; //합을 저장하는 변수 선언
    
    for (int i = 0; i < scores.length; i++) //length:5만큼 수행
        scores[i] = in.nextInt();
        
    for (int i = 0; i < scores.length; i++)
        sum += scores[i];       
       
    System.out.println("평균 = " + sum / 5.0); //평균값 출력
          
    }
}

배열의 선언

(1) int[] scores; 
(2) int scores[];
(3) int scores[5]; (X)

 배열의 선언과 생성

(1) int[] scores = {100, 90, 50, 95, 85}; 
(2) int[] scores = new int[] {100, 90, 50, 95, 85};

(3) int[] scores;

scores = new int[] {100, 90, 50, 95, 85};

(4) (XXX)

int[] scores;
scores = {100, 90, 50, 95, 85};

 

배열 원소 접근 

 

  배열이름[인덱스];

 

배열의 크기

  • 배열이 생성될 때 배열의 크기 결정됨
  • 배열의 length 필드가 배열의 크기를 나타냄. 예) scores가 가리키는 배열의 크기는 scores.length

다차원 배열

  • 선언과 초기화 
int [][] scores = {{100,90,50,95,85},{70,60,50,40,75},{90,80,70,60,50}};

 

동적 배열

import java.util.ArrayList;
import java.util Scanner;

public class ArrayListDemo {
	public static void main(String[] args){
    Scanner in = new Scanner(System.in);
    ArrayList<Integer> scores = new ArrayList<>();
    int data;
    int sum = 0;
    
    while ((data = in.nextInt()) >= 0) //data값 0보다 클때까지 입력 받음
    	scores.add(data); //동적배열에 추가
        
    for (int i = 0; i < scores.size(); i++) //동적배열에 크기 얻기 
    	sum += scores.get(i);
        
    System.out.println("평균 = "+ (double)sum / scores.size());        
    }
}
  • ArrayList 객체 생성
ArrayList<참조타입> 참조 변수 = new ArrayList<>();
  • ArrayList 원소 접근
참조변수.add(데이터) //데이터를 동적 배열에 원소로 추가
참조변수.remove(인덱스번호) //동적배열에서 인덱스 번호의 원소 제거
참조변수.get(인덱스번호) //동적배열에서 인덱스 번호의 원소를 가져오기
참조변수.size() //동적배열에 포함된 원소 개수

 

배열을 위한 반복문

  • for~each 반복문
  • 특정 원소를 나타내기 위한 인덱스를 사용하지 않는다. 

public class ForEachDemo{
	public static void main(String[] args) {
    
    int[] one2five = {0,1,2,3};
    int sum = 0;
    
    
    for (int x = 0; x < one2five.length; x++) //(1) 
        one2five[x]++; //(2)
        
    for (int x : one2five) //(3)
    	sum += x;
        
    System.out.println("평균 = " + sum / 5.0);
        
    }

}

(1) final int x로 변경하면 x++에서 오류가 발생한다. 왜?! 상수처리니까!

(2) for문은 특정 원소에 접근 가능하지만, for~each문은 할 수 없다. 

(3) final이 없어도 변수 x는 final int 타입이다. 

 

배열 응용 

 

메서드의 인수(argument)로 배열 전달

  • Call by value에 따라, 배열의 참조 값이 (메모리 주소값이) 복사되어 넘어간다. 예) n값 업데이트 되면, x값이 바뀐다.
  • 배열 객체를 매개 변수로 복사한다는 의미가 아니다. 
  • 해당 메모리 주소가 가리키는 값을 업데이트 👉결과값 또한 업데이트 된다. 

public class IncrementDemo{
	public static void main(String[] args) { //매개변수 String 타입 배열로!
    int [] x = { 0 };
    System.out.println("호출전의 x[0] =" + x[0]);
    
    increment(x);
    System.out.println("호출후의 x[0] =" + x[0]);           
    }

 	public static void increment(int[] n) { //배열의 참조변수: 매개변수
    
    System.out.println("increment 메서드 안에서");
    System.out.println("n[0] = " + n[0] + "---> ");
    n[0]++;
    System.out.println("n[0] = " + n[0]);
        
    }

}

output:

호출 전의 x[0] = 0

increment() 메서드 안에서 n[0] = 0 ------> n[0] = 1

호출 후의 x[0] = 1

 

예제2

public class MainArgumentDemo {
	public static void main(String[] args){
    if (args.length == 2) {
    	int i = Integer.parseInt(args[1]);
        nPrintln(args[0], i); //1번째 argument에 대한 함수를 호출한다. *
        } else
             System.out.println("푸린이 출몰했다!");    
    }
    
    public static void nPrintln(String s, int n) { //*
    	for (int i = 0; i < n; i++) 
        	System.out.println(s);        
    }        
 }

가변 개수(variable length) 인수

 

public static void Varargs(String... str) {

 

  • 한개의 가변 개수 매개변수만 사용 가능하고, 가변 개수 매개변수는 마지막에 위치한다. 
  • 가변 개수 인수를 가진 메서드를 호출하면 내부적으로 배열을 생성해 처리한다. 

합출력 프로그램

public class VarArgsDemo {
	public static void main(String[] args){
    	printSum(1, 2, 3, 4, 5);
        printSum(10,20,30);
            
    }
    
    public static void printSum(int... v){
    int sum = 0;
    for (int i : v)
    	sum += i;
        
    System.out.println(sum);    
    }
}

객체의 배열: 객체를 참조하는 주소를 원소로 구성한다

 

예) Ball 클래스의 객체로 구성된 배열을 선언하고 초기화한다. 

 

Ball[] balls = new Ball[5]; //5개의 Ball객체를 참조할 변수 준비

생성자를 호출해 Ball 객체를 생성해야 한다.

 열거 타입의 필요성

 

의미상 이상한 값을 대입해도 컴파일러는 인지하지 못한다! 

  • 제한된 수의 일이나 사건 등에 대해 숫자로 표현한다. 
  • 제한된 사건에 대해 숫자 대신 상수를 정의해서 부여한다.

열거 타입과 응용

public class EnumDemo{
	public static void main(String[] args) {
    	Direction direction = Direction.LEFT;
        if (direction == Direction.LEFT)
        	System.out.println(Direction.LEFT + "은 왼쪽");
        else
        	System.out.println(Direction.RIGHT + "은 오른쪽");
        
        for(Direction d : Direction.values())
        	System.out.println(d.name()); //상수이름
            
        System.out.println(Direction.valueOf("LEFT"));
                  
    }
	
}

enum Direction {
	LEFT("왼쪽"), RIGHT("오른쪽");
    
    private String s;
    
    Direction(String s) {
    	this.s = s;
    
    }
    
    public String toString(){
    	return s;    
    }
}

output:

왼쪽은 왼쪽

LEFT

RIGHT

왼쪽

 

  • 열거 타입: 서로 연관된 사건들을 모아 상수로 정의한 java.lang.Enum 클래스의 자식 클래스

 

  •   선언
enum 열거타입이름 {상수 목록}
/////

enum Gender { MALE, FEMALE } //클래스 타입: enum, 열거 타입 이름: Gender, 상수 목록: MALE, FEMALE
  • 일종의 클래스 타입인 열거 타입도 생성자, 필드 및 메서드 가질 수 있다.
  • 열거 타입 상수는 생성자에 의한 인스턴스이다.
  • 이때 생성자, 필드 및 메서드와 열거 타입 상수를 구분하기 위해 다음과 같이 열거 타입 상수 뒤에 세미콜론을 추가해야한다. 
enum 열거타입이름 {

    열거타입상수1, 열거타입상수2, ... ;
    //필드
    //생성자
    //메서드

}