SyntaxHighlighter.all(); 'Java' 카테고리의 글 목록 :: 게을러지고 싶어 부지런한 개발자

Arrays.asList()로 만들어서 그 중 원소 하나를 삭제하려 했더니 자꾸만 뜨는 java.lang.UnsupportedOperationException: null

아래처럼 하면 저 에러가 자꾸뜬다..

List<String> strList = Arrays.asList(new String[] {"A","B","C","D","E"});
strList.removeIf(data -> data.equals("A"));

 

어떻게 해결해야 할까? 찾아보니 Arrays.asList 로 생성한 리스트는 고정되어 있어 원소를 제거할 수 없다고 한다

그래서 아래와 같이 new ArrayList<>()  Arrays.asList 코드를 감싸서 리스트를 생성해야 리스트 원소를 삭제할 수 있다

List<String> strList = new ArrayList<>(Arrays.asList(new String[] {"A","B","C","D","E"}));
strList.removeIf(data -> data.equals("A"));

split과 tokenizer 모두 토큰으로 문자열을 나누는 방법


split()

String클래스의 메소드
지정한 구분자으로 문자열을 나눠 배열에 저장
| 로 여러개의 구분자를 정할 수 있음

ex) str.split("&" "/" | "+");
공백도 문자열로 추가가 됨 (아래 예시 참고)

 

 


StringTokenizer

클래스이므로 객체를 생성하고 사용
구분자를 생략하면 공백이 기본 구분자
지정한 한가지 구분자로만 문자열을 나눌 수 있음

ex) StringTokenizer str = new StringTokenizer([문자열],"구분자");
공백은 무시 됨 (아래 예시 참고)

객체생성하면 메소드 사용가능해서 편함
-countTokens() : 남아있는 토큰수 int 반환
-hasMoreTokens() : 토큰 남아있는지 여부 boolean 반환
-nextToken() : 토큰 String 반환

 

 

 

 

출처: 개미는 뜐뜐님의 블로그 

mybatis를 공부하다 보니 아래와 같은 설명이 있다.

 

마이바티스는 개발자가 지정한 SQL, 저장프로시저 그리고 몇가지 고급 매핑을 지원하는 퍼시스턴스 프레임워크

 

퍼시스턴스(Persitence)

퍼시스턴스는 데이터의 지속성을 의미. 즉 애플리케이션을 종료하고 다시 실행하더라도 이전에 저장한 데이터를 다시 불러올수있는 기술.

 

 

프레임워크(Framework)

라이브러리가(library)가 개발에 필요한 도구들을 단순히 나열해 놓은 것이라면 프레임워크(framework)는 동작에 필요한 구조를 어느 정도 완성해 놓은 반제품 형태의 도구입니다.

 

 

퍼시스턴스 프레임워크

퍼시스턴스 프레이임워크는 데이터의 저장, 조회, 변경, 삭제를 다루는 클래스 및 설정 파일들의 집합

퍼시턴스 프레임워크를 사용하면 JDBC프로그래밍의 복잡함이나 번거로움 없이 간단한 작업만으로 데이터베이스와 연동되는 시스템을 빠르게 개발할 수 있습니다. 안정적인 구동도 보장.

 

 

퍼시스턴스 프레임워크 종류

- SQL문장으로 직접 DB데이터를 다루는 'SQL 맵퍼(mapper)' : mybatis

- 자바 객체를 통해 간접적으로 DB데이터를 다루는 '객체 관계 맵퍼(Object-Relational mapper)' : 하이버네이트(Hibernate)

 

Strinig to int

String str= "123";

int n = Integer.parseInt(str);

 

int to String

int n= 123;

String str = Integer.toString(n);

 




여기서 기본적으로 4가지 아스키 코드를 외우고있으면 활용하실때 편합니다.

Enter = 13,    숫자 0 = 48,     대문자 A = 65 ,     소문자 a = 97

​이 4가지는 꼭 외우고 있도록 합시다.

 

 

방법 1)

char a = 'A';

int result = a;   // char는 바로 int로 집어넣어 형변환

System.out.println(a); 

 

방법 2)

String a = "A";

int result= a.charAt(0);  // String은 charAt()메소드 사용하여 int로 

System.out.println(a); 

 

=====================

반대로 10진수에서 아스키코드로 변환하는 방법은?

int n = 65;

System.out.println((char)n);    // 출력결과 : A 

 Call by value, Call by reference ?

 

 위 두 내용은 메소드(함수)에서 인자값을 받을 때 어떤식으로 받아 올 것 인지에 대한 방식이다.

 뜻 그대로 '값에 의한 호출' 그리고 '참조에 의한 호출' 인데 그 내용은 예시를 들어 설명해보겠다.

 

 

 Call by value

메소드 호출 시에 사용되는 인자의 메모리에 저장되어 있는 값(value)을 복사하여 보낸다.

무슨 뜻이냐면 int a =3 이라는 문구가 있으면 

메소드에서 인자값을 받을 때 a라는 자체에 주소를 받는게 아니라 a의 값인 3을 받아 처리하는 방식이다.

 

 

 Call by reference

메소드 호출 시 사용되는 인자 값의 메모리에 저장되어있는 주소(Address)를 복사하여 보낸다.

값이 아니라 인자 그자체에 주소 값을 보낸다. 

 

 

 

결론을 먼저 말하자면 자바는 Call by value  방식으로 인자값을 받는다.

 

결과 값은 이렇다

비포

안녕잘가

에프터

안녕잘가

 

 왜 스왑 메소드를 이용해서 서로를 바꿔준 것 같지만 바뀌지 않았을까?? Call by value 방식이기 때문이다. 

스왑 메소드가 받는 두 인자는 인자값에 주소, 즉 인자 그자체를 받는 것이 아니라 인자의 값을 복사해서 받는다.

즉 String one 에는 a에 값인 "안녕" 에 값이 (String 은 참조 변수 이므로 "안녕" 에 주소 값이 복사)

마찬가지로 two 에도 b의 주소가아닌 b값에 주소가 복사 되어진다.

 

 

 

 이렇게 메인 메소드의 a, b와 swapS 메소드의 one two는 서로 같은 값을 참조할 뿐 이다.

 이렇게 메소드 내에서는 변화가 이루어 지지만 메소드가 닫히면 swapS에 있던 정보는 다 사라지므로 메인 메소드에 영향을 주지 못한다.

만약 위 코드에 있는 //주석문을 활성화 시키면 바뀐 값을 출력 할 것이다.

 

 

 만약 call by Reference 방식 이였으면 메소드내에서 one two가 a, b의 주소값을 받아 곧 a=one b=two 이고 메소드 수행으로 서로값이 바뀌니 메소드 수행을 하고 나서도 a, b가 바뀌어 있을 것이다. 

 

 

하지만 이러한 효과를 내는 방법은 있다.

 

 

 

 

swap() 호출 전 : a = 10, b = 20

swap() 호출 전 : a = 20, b = 10

 

이렇게 값이 바뀌는 걸 볼 수 있다.

 

그림으로 보자

 

마찬가지로 one과 two는 값의 주소를(call by value) 복사받아 같은 인스턴스를 참조하는 것 이지만..

 

 

이렇게 참조 되어지는 값을 바꾸어 주어 마치 call by reference 가 이루어진 것 처럼 보인다.

 

비슷한 예로 

 

1 8

8 1

 

이렇게 가르키고 있는 공간의 값을 바꾸어 주면 된다.

 

 

 

정리하자면 !!

자바는 !

기본형 타입 변수와 참조형 타입 변수가 있는데 

둘 다! 상관없이 call by value 방식으로 메소드에서 받아진다 !

 

대신 기본형 타입은 그 값을 복사 해서 주지만

참조형 타입은 값의 래퍼런스(주소)가 저장되는 것이므로 그 값의  래퍼런스가 복사 되어진다 !

 

즉 값의 래퍼런스가 call by value 방식으로 넘어간다!.

 

말이 긴데 어찌되었든 call by value 방식이다 자바는..

 

 

 

참고

https://sleepyeyes.tistory.com/11

1. System 클래스의 arraycopy() 메소드 (배열의 길이를 마음대로 늘일 수 O)

2. Arrays 클래스의 copyOf() 메소드 (배열의 길이를 마음대로 늘일 수 O)

3. Object 클래스의 clone() 메소드(전 배열과 같은 길이의 배열밖에 만들 수 없음)

4. for 문과 인덱스를 이용한 복사

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 
public class Main {
    public static void main(String[] args) {
        int[] arr1 = new int[]{12345};
        int newLen = 10;
        
        // 1. System 클래스의 arraycopy() 메소드
        int[] arr2 = new int[newLen];
        System.arraycopy(arr1, 0, arr2, 0, arr1.length);
        
        for (int i = 0; i < arr2.length; i++) {
            System.out.print(arr2[i] + " ");        // 1 2 3 4 5 0 0 0 0 0 
        }
        System.out.println();
        
        // 2. Arrays 클래스의 copyOf() 메소드
        int[] arr3 = Arrays.copyOf(arr1, 10);
        
        for (int i = 0; i < arr3.length; i++) {
            System.out.print(arr3[i] + " ");       // 1 2 3 4 5 0 0 0 0 0 
        }
        System.out.println();
        
        // 3. Object 클래스의 clone() 메소드
        int[] arr4 = (int[])arr1.clone();
        
        for (int i = 0; i < arr4.length; i++) {
            System.out.print(arr4[i] + " ");        // 1 2 3 4 5 
        }
        System.out.println();
        
        // 4. for 문과 인덱스를 이용한 복사
        int[] arr5 = new int[newLen];
        
        for (int i = 0; i < arr1.length; i++) {
            arr5[i] = arr1[i];
        }
        
        for (int i = 0; i < arr5.length; i++) {
            System.out.print(arr5[i] + " ");   // 1 2 3 4 5 0 0 0 0 0 
        }
    }
}
 
cs

continue문

루프 내에서 해당 루프의 나머지 부분을 건너뛰고, 바로 다음 조건식의 판단으로 넘어가게 해줌

 

다음 예제는 1부터 100까지의 정수 중에서 5의 배수와 7의 배수를 모두 출력하는 예제입니다.

 

public class prog {
	public static void main(String[] args) {
		for (int i = 1; i <= 100; i++) {
			if (i % 5 == 0 || i % 7 == 0) {
				System.out.println(i);
			} else {
				continue;
			}
		}
	}
}

출력결과

5
7
10
....
84
85
90
91
95
98
100

 

break 문

break 문은 루프 내에서 사용하여 해당 반복문을 완전히 종료시킨 뒤, 반복문 바로 다음에 위치한 명령문을 실행합니다.

즉 루프 내에서 조건식의 판단 결과와 상관없이 반복문을 완전히 빠져나가고 싶을 때 사용합니다.

 

다음 예제는 1부터 100까지의 합을 무한 루프를 통해 구하는 예제입니다.

int num = 1, sum = 0;

 

while (true) { // 무한 루프

    sum += num;

    if (num == 100) {

        break;

    }

    num++;

}

System.out.println(sum);

출력결과   5050

 

여기서 유의할 점!!! 

 

일반적인 break 문은 단 하나의 반복문만을 빠져나가게 해줍니다.

따라서 여러 반복문이 중첩된 상황에서 한 번에 모든 반복문을 빠져나가거나, 특정 반복문까지만 빠져나가고 싶을 때는 다른 방법을 사용해야 합니다.

 

이때 사용할 수 있는 방법이 바로 반복문에 이름(label)을 설정하는 것입니다.

가장 바깥쪽 반복문이나 빠져나가고 싶은 특정 반복문에 이름을 설정한 후, break 키워드 다음에 해당 이름을 명시하면 됩니다.

그러면 해당 break 키워드는 현재 반복문이 아닌 해당 이름의 반복문 바로 다음으로 프로그램의 실행을 옮겨줍니다.

 

이에대한 예제는 구구단 2단부터 4단까지 출력하는 코드입니다.

allLoop :

for (int i = 2; i < 10; i++) {  // 1번째 반복문

    for (int j = 2; j < 10; j++) { // 2번째 반복문

        if (i == 5) {

            break allLoop;

        }

        System.out.println(i + " * " + j + " = " + (i * j));

    }

}

출력결과

2 * 2 = 4

2 * 3 = 6

2 * 4 = 8

2 * 5 = 10

...

4 * 6 = 24

4 * 7 = 28

4 * 8 = 32

4 * 9 = 36

 

 

 

 

 

 

+ Recent posts