Search

반응형

'Java'에 해당되는 글 52건

  1. 2020.05.08 [자바]Random 클래스로 난수를 만들어 보기 - long seed, java.util.Random;
  2. 2020.05.03 [자바]StringBuffer vs. String 메모리 관리하기.
반응형

안녕하세요. 신기한 연구소의 티보이입니다.

이번은 자바 프로그램을 개발하다 보면 가끔 사용하는 Random(난수) 클래스에 대해 알아볼게요.

개발에 잘 활용하세요~

Random클래스란?

순서가 없는 연속적인 임의의 수를 난수라고 합니다.

난수를 만들어 주는 클래스가 Random클래스이며 java.util 패키지에 포함되어 있습니다.

import java.util.Random; 

 

생성자.

Random r = new Random(); //기본 생성자기본생성자 

Random r = new Random(long seed); //seed 설정 생성자 

 

메서드.

Next, nextBoolean, nextDouble, nextFloat, nextGaussian, nextInt, nextLong, setSeed 

 

사용 예.

우선 기본 생성자를 사용해서 객체를 인스턴스화 하고 자주 사용하는 nextInt() 메서드를 이용하면 난수를 얻을 수 있습니다.

1
2
3
Random r101 = new Random();
                
System.out.println(r101.nextInt());
cs

 

결과 

-2057661722
1761664520

이때 만들어지는 난수는 양수, 음수 상관없이 숫자의 크기도 맘대로 불규칙적으로 만들어집니다.

로또 숫자처럼 원하는 범위 내에서 만들고 싶다면 nextInt메서드에 범위 값을 넘겨주면 됩니다.

1
2
3
4
5
6
7
8
9
        Random r0 = new Random(); 
        
        System.out.println(r0.nextInt(1000));
        System.out.println(r0.nextInt(1000));
        
        Random r1 = new Random(); 
        
        System.out.println(r1.nextInt(1000));
        System.out.println(r1.nextInt(1000));    
cs

 

결과.
950
148
888
607

r0 객체로 random 난수를 만드는데 "1000"이라는 범위를 설정했습니다. nextInt(1000);

이 범위 안의 정수값이 임의로 표출됩니다.

또한 r0객체에서 연속으로 nextInt 를 사용하거나 또는 새로 r1객체를 사용해서 만들거나 항상 새로운 난수를 주어진 범위 내에서 만들게 됩니다.

보통 이 정도면 기본적인 난수를 만들어 사용하는데 문제가 없습니다.

 

두 번째 seed를 사용하는 생성자를 보겠습니다..

특징은.

Seed값을 넣으면 이 초기값을 가지고 난수를 만듭니다.

기본 생성자와 다른 점은,

기본 생성자는 객체를 인스턴스화 할 때나 또는 nextInt() 메서드를 실행할 때마다 위 예제처럼 중복될 가능성이 거의 없는 새로운 난수를 만듭니다.

Seed값을 받는 생성자는 객체를 인스턴스화 할 때는 계속 같은 값을 만듭니다.

1
2
3
4
5
6
7
8
9
        Random r2 = new Random(8); 
            
        System.out.println(r2.nextInt(1000));
        System.out.println(r2.nextInt(1000));
        
        Random r3 = new Random(8); 
        
        System.out.println(r3.nextInt(1000));
        System.out.println(r3.nextInt(1000));    
cs
결과.
364
956
364
956

결과를 확인해 보면 r2와 r3의 seed 값이 "8"로 같습니다.

다른 Random클래스 객체로 인스턴스화 했지만,

1000 범위값의 난수는

364로 같습니다.

하지만 한 번 인스턴스화 한 상태에서 nextInt()만 호출 시 다른 값을 만듭니다.

중요한 것은 이렇게 만들었다고 해도 다시 객체를 인스턴스화 하면 또 같은 순서대로 난수가 나옵니다. 규칙적 난수라고 하면 될까요?

위 예제를 보면 r2나 r3로 다시 종료하고 실행해도 같은 값이 순서대로 나옵니다.

seed값을 다르게 넣거나 범위값이 다르게 넣으면 다른 난수가 규칙적으로 나옵니다.

위 메서드 목록에 보면 setSeed가 있는데,

일반 생성자로 생성한 Random 클래스 객체를 해당 메서드를 통해 중간에 seed값을 설정할 수 있게 해줍니다.

정리해 보면,

일반 생성자로 만든 난수는 로또 번호 자동 생성기 같이 수시로 그때마다 다르게 조건에 맞는 난수가 필요한 경우에 사용하면 됩니다.

Seed를 받는 생성자의 경우는 난수를 만든다는 것은 같지만 seed값에 의해 객체가 인스턴스화 될 때마다 같은 난수를 만들어 주기에 그에 맞는 용도로 사용하면 됩니다.

예를 들어 데이터베이스에 보안상의 이유로 직원의 인증번호를 그대로 입력하면 안 되는 상황이 있다고 가정합니다. 직원이 인증번호를 저장할 때 seed값에 인증번호를 넣고 난수를 받아서 저장하면 데이터베이스에는 직원의 인증번호가 저장되지 않고 생성된 난수가 저장 됩니다.

이후 인증 시도 시 직원이 인증번호를 seed로 해서 난수로 만든 수와 데이터베이스의 난수와 비교했을 때 같으면 인증이 되도록 할 수 있겠네요.

이런 방식을 응용해서 잘 활용하면 될 듯합니다.

마치겠습니다. 즐코딩 하세요~

반응형
반응형

즐코딩 하고 계시나요?

코딩은 즐겁게 해야 시간도 잘갑니다. ㅎㅎ

이번 포스팅은 StringBufferString 타입에 대해 설명해봅니다.

예전에 자바 초보시절 겪었던 일입니다.

그때는 나름 한다고 생각했지만 사실 초보였지요.

 델파이(Delphi)나 비주얼베이직(VB) 개발자에서 자바로 건너온 지 그리 오래 되지 않았었고,

깊이 있게 자바를 생각하지 않고 사용하던 시절이었네요..ㅋㅋ

여튼 자동으로 HTML을 만드는 프로그램을 만들던 중 문자 데이터를 결합해야 하는데..

그냥 String으로 선언하고 그 변수에 += 로 계속 이어 나갔습니다.

어떤 결과가 나왔을지 여러분은 아시겠죠?

메모리 오버나고 속도 개 느려지고 ㅋㅋ ..

왜 그럴까? 이게 안되는게 말이 되나? 그럼 어쩌란말인가?

라면서 고민하던 중 큰 실수를 했다는 것을 알았답니다.

String 변수에 +나 += 로 계속 문자열을 붙이면 선언한 변수 하나에 붙여지는게 아니라,

새로 메모리를 차지하면서 중복되는 정보가 계속 쌓이는 구조였습니다.

그래서 여러개의 문자열을 대량으로 이어 붙이는 경우 (네트워크 전송 데이터 등)

String으로 사용하면 안되는거에요.

하나의 변수에 대량의 문자열들을 이어 붙이기 위해서는 StringBuffer 클래스의 객체를 이용하면 됩니다.

그러면 단 하나의 객체로 데이터가 쭉 이어져서 붙여집니다.

예를 통해서 StringBuffer 클래스로 객체도 생성하고 해당 메소드의 사용법도 살펴보겠습니다.

 

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
StringBuffer sb1 = new StringBuffer();
 
sb1.append("abcde");
System.out.println(sb1.toString()); 
 
sb1.delete(24);
System.out.println(sb1.toString()); 
 
sb1.deleteCharAt(0);
System.out.println(sb1.toString()); 
 
sb1.insert(0"a");
sb1.insert(2"cd");
System.out.println(sb1.toString()); 
 
System.out.println(sb1.indexOf("c"));
 
System.out.println(sb1.indexOf("f"));
        
System.out.println(sb1.lastIndexOf("d"));
 
sb1.replace(34"234");        
 
System.out.println(sb1.toString());
 
System.out.println(sb1.substring(2));
 
System.out.println(sb1.length());
 
 
StringBuffer sb2 = new StringBuffer();
 
sb2.append("abcdefabcdef");
 
System.out.println(sb2.indexOf("c"));
System.out.println(sb2.indexOf("c"5));
 
System.out.println(sb2.lastIndexOf("c"));
System.out.println(sb2.lastIndexOf("c"8));
System.out.println(sb2.lastIndexOf("c"7));
cs

 

코딩에 필요하면 복사해서 사용하면 됩니다. ^^

우선 StringBuffer 객체를 생성합니다.

 

StringBuffer sb1 = new StringBuffer();

이렇게요.

sb1에 원하는 문자열들을 집어 넣습니다.

 

sb1.append("abcde");

append 메서드는 제일 마지막 부분에 입력한 문자열을 붙입니다.

결과를 확인할 때는 sb1이 객체이므로 toString() 메서드를 이용합니다.

 

System.out.println(sb1.toString()); 

결과는 "abcde"가 나옵니다.

이 상태에서 sb1.append("fgh");를 하면 제일 뒤에 "fgh"를 붙여서 "abcdefgh"가 됩니다.

 

sb1.delete(24);

delete메소드는 문자열을 삭제하는 기능입니다.

파라메터는 문자열 시작 인덱스에서 삭제하고 싶은 문자열 다음 인덱스로 설정합니다.

(2, 4)로 2에서 시작하니 "c"부터 삭제하면서 4 앞까지 삭제하니 "d"까지 삭제하겠네요.

결과는 "abe"가 나옵니다. 주의할 점은 두번째 파라메터인 4까지가 아니라 4 앞까지입니다.

 

sb1.deleteCharAt(0);

문자 한개의 위치를 지정해서 삭제합니다. 위치 인덱스가 0이므로 "a"만 삭제 됩니다.

 

sb1.insert(0"a");

sb1.insert(2"cd");

insert 메서드는 원하는 위치에 문자 또는 문자열을 추가할 수 있습니다.

두번째 (2, "cd")는 2번 인덱스와 3번 인덱스 사이에 "cd"를 넣는거에요. 3번이 뒤로 밀려납니다.

 

sb1.indexOf("c");

sb1에서 c의 위치 인덱스를 반환합니다. 

결과는 "2"가 나옵니다.

 

sb1.indexOf("f");

"f"를 찾지만 문자열에 없습니다. 

결과가 없는 경우는 "-1"을 리턴합니다.

 

System.out.println(sb1.lastIndexOf("d"));

lastIndexOf 메서드는 "d"를 찾을 때 처음부터 찾는게 아니라 문자열 제일 뒤에서부터 찾습니다.

그리고 위치가 확인되면 위치 인덱스는 앞에서부터 계산해서 보여줍니다.

결과는 "3"이 나옵니다. 

sb1.replace(34"234");

replace 메서드는 지정한 위치에 원하는 문자열을 대체하는 겁니다.

insert는 기존 문자열 사이에 집어 넣지만 replace는 지정한 위치의 문자 대신해서 넣는데 지정한 길이보다 길어도 변환이 됩니다.

결과는 "abc234e"가 나옵니다.

 

sb1.substring(2);

원하는 인덱스 위치를 넣으면 그 위치부터 뒤로 끝까지 문자들을 반환합니다.

결과는 "c234e"가 나옵니다.

 

sb1.length();

문자열 전체 길이를 반환합니다.

결과는 "7"이 나옵니다.

 

sb2.indexOf("c"5);

이 경우는 문자 "c"를 5번째 인덱스부터 찾아서 반환하라는 의미입니다.

결과는 두번째 "c"의 위치인 "8"이 반환됩니다. 첫번째 "c"의 인덱스는 2이지만 5부터 찾으라고 했기 때문입니다.

 

sb2.lastIndexOf("c"8);

이 메서드는 "c"문자를 8번째 문자열부터 시작해서 찾습니다. 두번째 "c"의 위치가 8이기에 두번째 위치인 "8"이 나옵니다.

 

sb2.lastIndexOf("c", 7);

이렇게 7로 바꾸게 되면 8번째 "c"가 포함되지 않기에 2번 인덱스의 "c"가 검색됩니다.

그래서 결과는 "2"가 나옵니다.

네트워크 전송 데이터를 결합하거나 또는 긴 문자열을 다룰 때는 StringBuffer를 사용해보세요.

즐코딩하세요~

 

반응형