[자바 기초 문법] 문자열과 배열
문자열의 선언과 생성
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, ... ;
//필드
//생성자
//메서드
}