자료를 저장하기 위한 메모리 공간(그릇)으로 타입에 따라 크기가 달라지는 특성
메모리 공간에 값(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
와 같이 프로그래머 책임 하에 명령어 실행
오버플로우 연산은 값이 깨지니 연산 과정 도중 오버플로우 되지 않도록 주의
문자열에서 단일 문자를 꺼내오는 것은 charAt(i)
로 꺼내거나, toCharArray()
를 통해 꺼내올 수 있다.
..이하까지 기본적인 내용 서술
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는 소문자로, 클래스는 대문자로 시작 하는 것을 잊지 말자.
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")); //가변적으로 내부의 값이 변화한다.
다시 위의 예문 일부를 본다면 차이를 이제 알 수 있게 되었다.
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]);
}
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(); //소문자로
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
String data = 100+""; //문자열로 만들기
data = String.valueOf(100); //문자열로 만들기2(권장 - 더 빠름)
//공백제거
data = " H e l l o ";
data = data.trim(); //앞뒤공백제거
data = data.replace(" ", ""); //전체 공백 제거
System.out.println(data);
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
/*
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)] + " ");
}
}
인상깊었던 지그재그 배열 줄이기