230116 - JAVA 기본 문법, 배열

블랑·2023년 1월 15일
0

Daily Study

목록 보기
3/5
post-thumbnail

JAVA 기본

Variable

자료를 저장하기 위한 메모리 공간(그릇)으로 타입에 따라 크기가 달라지는 특성
메모리 공간에 값(value)을 할당(assign) 후 사용

Type이란? 다른 글 참조.
: https://velog.io/@csg1353/230111-JAVA-%EA%B8%B0%EC%B4%88#4-%EB%B0%B0%EC%97%B4

	public static void main(String[] args) {
		int i1 = Integer.MAX_VALUE;
		int i2 = i1+1;
		System.out.println(i2);
	}

다음 구문의 계산 값은? 오버플로우로 인해 -2147483648이 결과값으로 출력된다.

실수 연산


public class test_230116 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		float f1 = 2.0f;
		float f2 = 1.1f;
		float f3 = f1 - f2;
		System.out.println(f3); //float끼리의 연산
		
		double d1 = 2.0;
		double d2 = 1.1;
		double d3 = d1-d2;
		System.out.println(d3); //double 연산
		
		System.out.println(((int)(d1*100)-(int)(d2*100)) /100); //int형변환 연산
		
	}

}

실수의 연산은 정확하지 않다. 유효 자리수를 이용해 반올림 처리한다.

형변환

Type Casting : 변수의 타입을 다른 형태로 변환하는 것

reference는 reference끼리, primitive는 primitive끼리 변환되며 boolean은 다른 타입과 호환되지 않는다. 이러한 형 변환은 Wrapper 클래스를 사용하여 실행한다.

묵시적 형변환 : 더 큰 값의 범위로 변환하는 경우 값 손실이 없기에 JVM이 서비스 가능
명시적 형변환 : 작은값의 볌위로 변환하는 경우 값 손실이 발행하고 사용자 책임.
--> 그렇기에 (int)a 와 같이 프로그래머 책임 하에 명령어 실행

오버플로우 연산은 값이 깨지니 연산 과정 도중 오버플로우 되지 않도록 주의

char?

문자열에서 단일 문자를 꺼내오는 것은 charAt(i)로 꺼내거나, toCharArray()를 통해 꺼내올 수 있다.
..이하까지 기본적인 내용 서술

다차원 배열

Array 순회 / 탐색

2D Arr 기준점으로,
상하는 행값 변화 (ex : [x][y]일 경우 위아래는 [x-1][y] / [x+1][y])
좌우는 열값 변화 (ex : [x][y]일 경우 좌우는 [x][y-1] / [x][y+1])

사방탐색의 포맷은 다음과 같이 할 수 있다.
해당 dr과 dc값을 각각 적용하면 상/하/좌/우 로 이동 가능하게 한다.

int[] dr = {-1,0,1,0};
int[] dc = {0,1,0,-1};


for(int d = 0; d < 4; d++){
int nr = x+dr[d]
int nc = y+dc[d]
}

//2차원 배열 표시
int [][] drc = {
				{-1,0}
                {0,1}
                {1,0}
                {0,-1}
                };
for(int d = 0; d < 4; d++){
int nr = x+drc[d][0]
int nc = y+drc[d][1]

}

오후

자바의 구성 요소 - 이름 규칙


public class NamingTest {
	public static void main(String[] args) {
		/*
		 * 클래스 : Integer String[] System = 대문자로 시작
		 * 변수 : args i j maxValue minValue out = 소문자로 시작
		 * 메서드 : main() println() = 괄호
		 * 상수 : MAX_VALUE, MIN_VALUE = 전부 대문자면서 언더바 사용
		 */
		int i =  100;
		int j = 200;
		int maxValue = Integer.MAX_VALUE;
		int minValue = Integer.MIN_VALUE;
		System.out.println(maxValue);
	}
}

이름 규칙을 잘 사용하면 JAVA의 구성 요소를 전부 쉽게 확인할 수 있다.
협업 등에서 네이밍 룰을 잘 지켜야 프로젝트 진행에 애로사항이 없을 것이다.
pakage는 소문자로, 클래스는 대문자로 시작 하는 것을 잊지 말자.

StringAPI(String, StringBuffer, StringBuilder)


public class StringTest {
	/* 자바의 문자열 관련 API 클래스
	 * <불변>
	 * String
	 * 
	 * <가변>
	 * StringBuffer
	 * StringBuilder
	 */
	static void exam01() {
		String str1 = "a";
		StringBuffer str2 = new StringBuffer("a");
		StringBuffer str3 = new StringBuffer("a");
		
		System.out.println(str1.concat("b")); //str1의 값을 바꾸는 것이 아니다 -> 불변
		System.out.println(str2.append("b"));
		System.out.println(str3.append("b")); //가변적으로 내부의 값이 변화한다.
		
		System.out.println(str1);
		System.out.println(str2);
		System.out.println(str2);
	}
	public static void main(String[] args) {
		exam01();
		
	}
}
  • 결과

문자열은 참조형이므로, if문 등에서 if(String temp == "java")와 같이 직접적으로 비교하는 것은 위험하다.
왜냐하면 문자열 자체를 비교하는 것이 아닌 문자열이 저장되어 있는 주소(메모리 공간) 를 비교하는 것이다.


String a ="java"
String b ="java"

--> 여기서 b는 새로운 "java"라는 단어가 담긴 메모리 공간을 생성하는 것이 아니라, 
메모리 공간 내에 "java"라는 메모리를 가진 공간의 '주소' 가 들어있을 수도 있는 것이다.

따라서 문자열 내부를 비교하고 싶다면 관리되고 있는 내용 자체를 비교하는 .equals(str) 을 사용해야 한다.

만약 b += "hello" 라는 구문이 실행되면 "javahello"라는 문자열이 만들어질 것이다.
먼저 상수 테이블에 해당 내용이 있는지 확인하고 새로운 주소를 생성한다.

이 부분은 문자열의 상수 테이블을 조금 더 자세히 참고하자.

String s ="a";
for(int i=0; i< 100; i++){
	s += "i"
}

만약 다음과 같이 반복문을 돌리면 s1..s2...순으로 상수 테이블에 계속 반복해서 메모리 공간이 생성된다.

StringBuffer sb = new StringBuffer("a");
sb.append("b");

다음과 같은 방식은 어떨까?
sb라는 객체는 "a"라는 문자열 외에 16개의 공간을 추가로 확보한다.
이후 append에 따라서 공간에 추가적인 내용을 넣은 뒤 다시 공간을 확보한다.

즉, 메모리를 효율적이고 빠르게 사용할 수 있게 한다.
한 객체의 공간을 추가하는 것이 참조로 인한 새로운 메모리 공간을 만드는 것보다 효율적인 것은 당연하다.

그렇기에 백준 등에서 알고리즘 풀이 시 String 방식보다 StringBuffer 방식이 더더욱 효율적이고 빠르게 실행할 수 있는 것이다.

static void exam02() {
		String s1 = "a";
		//String 시간 측정
		long s = System.currentTimeMillis();
		for (int i = 0; i < 100000; i++) {
			s1+= i;
		}
		System.out.println("String 걸린 시간 : " + (System.currentTimeMillis() - s) / 1000d);
		
		StringBuffer s2 = new StringBuffer("a");
		//StringBuffer 시간 측정
		s = System.currentTimeMillis();
		for (int i = 0; i < 100000; i++) {
			s2.append(i);
		}
		System.out.println("StringBuffer 걸린 시간 : " + (System.currentTimeMillis() - s) / 1000d);
		
		StringBuilder s3 = new StringBuilder("a");
		//StringBuilder 시간 측정
		s = System.currentTimeMillis();
		for (int i = 0; i < 100000; i++) {
			s3.append(i);
		}
		System.out.println("StringBuilder 걸린 시간 : " + (System.currentTimeMillis() - s) / 1000d);
	}

다음과 같이 유의미한 시간 차이를 보일 수 있다.
StringBuffer는 동기화, StringBuiler는 비동기화 처리이며 이 두가지 요소도 조금의 시간적 차이가 존재한다.

		System.out.println(str1.concat("b")); //str1의 값을 바꾸는 것이 아니다. 새로운 메모리 공간 창조 -> 불변
		System.out.println(str2.append("b"));
		System.out.println(str3.append("b")); //가변적으로 내부의 값이 변화한다.

다시 위의 예문 일부를 본다면 차이를 이제 알 수 있게 되었다.

자주 쓰이는 StringAPI

charAt(), length(), toCharArray(),

String s = "hello";
		char ch = s.charAt(0); //char의 반환형
		System.out.println(ch);

		System.out.println(s.length()); //숫자 길이 반환
		
		for (int i = 0; i < s.length(); i++) {
			System.out.println(s.charAt(i));
		}
		
		s = "192781740";
		char[] arr = s.toCharArray(); //내용물을 char[] 형태로 반환
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}

[대소문자 관련] equals(), equalsIgnoreCase(), toUpperCase(), toLowerCase();

		s = "Hello";
		if(s.equals("hello")) {
			System.out.println("equals는 대소문자 비교");
		}
		if(s.equalsIgnoreCase("hello")) { //--Case나오면 대부분 대소문자 관련 메소드임.
			System.out.println("equalsIgnoreCase는 대소문자 무시");
		}
		
		s = s.toUpperCase(); //대문자로
		s = s.toLowerCase(); //소문자로
		

[문자열에서 특정 문자 찾기] .indexOf , .contains()

		s = "Hello Java";
		int idx = s.indexOf("llo");
		System.out.println(idx);
		
		idx = s.indexOf("a", idx+1); 
		//문자열에서 두 번째 a를 찾고싶다면, 반복함수선언을 한다.
		System.out.println(idx);
        
        boolean find = s.contains("llo"); //T/F로 찾았는지 아닌지 확인

문자열 형변환(+, valueOf()),

		// 문자열로 만들기+, valueOf
		String data = 100+""; 		//문자열로 만들기
		data = String.valueOf(100); //문자열로 만들기2(권장 - 더 빠름)

공백제거(trim(),replace())

		//공백제거
		data = "    H e l l o    ";
		data = data.trim(); //앞뒤공백제거
		data = data.replace(" ", ""); //전체 공백 제거
		System.out.println(data);

특정 문자열 검색(startsWith(),endsWith()), 문자열 추출(substring())

		String s1 = "3:2:3:1:2";
		String[] arr = s1.split(":");
		System.out.println(Arrays.toString(arr));
		
		s = "http://www.naver.com";
		System.out.println(s.startsWith("https://")); //특정한 문자열로 시작하는지? T/F
		System.out.println(s.endsWith(".jpg")); 	  //특정한 문자열로 끝나는지? T/F
		
		String contectPath = "/myserver"; //변수 부분을 제외한 나머지 부분을 제외하고 추출하고 싶다.
		s = "/myserver/login?id=a&pass=b";
		System.out.println(s.substring(contectPath.length()));
        --> /login?id=a&pass=b 
		

2D Array 실습

행 순회, 행역 순회, 열순회, 지그재그 순회

/*
		int count = 0;
		for (int i = 0; i < arr.length; i++) {
			if(count % 2 == 0) {
				for (int j = 0; j < arr[i].length; j++) {
					System.out.print(arr[i][j] + " ");
				}
			}
			else {
				for (int j = arr[i].length - 1 ; j >= 0; j--) {
					System.out.print(arr[i][j] + " ");
				}
			}
			System.out.println();
			count++;
		}
		*/
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < M; j++) {
				System.out.println(arr[i][j +(M - 1 - 2 * j) * (i % 2)] + " ");
			}
			
		}

인상깊었던 지그재그 배열 줄이기

사담

  • 띄어쓰기
    연산자 기준 띄어쓰기 할 것, for 다음 각주 띄어쓰기
profile
안녕하세요.

0개의 댓글