랜덤한 값을 뽑아내는데 쉽고 간편하게 쓸 수 있는 방법이 자바에서 제공해주는 랜덤함수를 쓰는 것이다.

크게 2가지를 이용할 수 있다.

 

첫번째, Random Class 이용하기

1
2
3
4
5
6
7
8
9
10
11
12
13
package{
  public class {
    public static void main(String arg[]) {
      Random random=new Random();
 
      System.out.println(random.nextInt());
      System.out.println(random.nextInt(10));
      System.out.println(random.nextBoolean());
      System.out.println(random.nextDouble());
    }
  }
}
 

 

두번째, Math Class이용하기

1
2
3
4
5
6
7
8
9
package{
  public class {
    public static void main(String arg[]) {
        int random=(int)(Math.random()*100)+1;
        System.out.println(random);
    }
  }
}
 

Math.random()으로 정수형 랜덤을 뽑아내는 경우 double인 반환값을 정수형 형변환을 통해 소수점을 잘라주는게 포인트 입니다. 

 

정수형의 경우 편하게 계산하기 위해 일반화시켜봤는데요.(물론 별거아니지만...)

new Random().nextInt(MaxValue-MinValue+1)+MinValue

(int)(Math.random()*MaxValue-MinValue+1)+MinValue

 

Random Class와 Math Class는 각기 다른 용도가 있습니다. 저의 경우 Random Class만 이용하는 편인데 살펴보다보니 random값을 자주 뽑을 필요가 없고 또한 다양한 형태로 뽑을 필요가 없다면 Math 클래스로 static한 random 메서드를 이용하는게 좀 더 효율적일수도 있을거 같다는 생각이 들기도하네요.

Posted by duehd88
,

stream read하기

Programing/java 2015. 2. 18. 01:47

inputStream을 읽을때 필요한 데이터를 모두 읽을때까지 대기하는 코드

result값으로 1024byte이하의 데이터가 전송되고 스트림이 종료되는 시나리오까지 고려한 코드

네트워크 스트림에서 주로 쓰이는 방법이다.

1
2
3
4
5
6
7
8
9
10
static final int BYTE_SIZE=1024;
int bytesRead=0;
int bytesToRead=BYTE_SIZE;
byte[] input=new byte[bytesToRead];
 
while(bytesRead<bytesToRead){
    int result=in.read(input,bytesRead,bytesToRead-bytesRead);
    if(result==-1){ break; }
    bytesRead+=result;
}

대기없이 inputStream이 한번에 읽을 수 있는 최소한의 byte수만큼만 읽기

조심해서 써야한다. available()같은 경우 stream의 끝에 이를 경우 0을 반환하기 때문에 이렇게 쓰이기 보단 stream이 남아 있는지 여부를 판단하고

없을 경우 stream을 사용할 수 있게 비워주는 식의 코드를 짜야하는 경우 사용하는 것이 좋다.

1
2
3
int bytesToRead=in.available();
byte[] input=new byte[bytesToRead];
in.read(input,0,bytesToRead);

 

Posted by duehd88
,
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
class Htonl{
    public static void main(String args[]){
        if(args.length<1){
            System.out.println("Usage : java Htonl");
            System.exit(0);
        }
 
        int value=Integer.parseInt(args[0]);
        int newValue=swap(value);
 
        System.out.println("big endian value : 0x" + Integer.toHexString(value));
        System.out.println("little endian value : 0x" + Integer.toHexString(newValue));
    }
 
    /*
     * Swapping byte orders of given numeric types
     */
    static short swap(short x){
        return (short)((x << 8) | ((x >> 8) & 0xff));
    }
 
    static char swap(char x){
        return (char)((x << 8) | ((x >> 8) & 0xff));
    }
 
    static int swap(int x){
        return (int)((swap((short)x) << 16) | (swap((short)(x >> 16)) & 0xffff));
    }
 
    static long swap(long x){
        return (long)(((long)swap((int)(x)) << 32) | ((long)swap((int)(x >> 32)) & 0xffffffffL));
    }
 
    static float swap(float x){
        return Float.intBitsToFloat(swap(Float.floatToRawIntBits(x)));
    }
 
    static double swap(double x){
        return Double.longBitsToDouble(swap(Double.doubleToRawLongBits(x)));
    }
}

'Programing > java' 카테고리의 다른 글

간단한 랜덤함수 사용법  (0) 2015.04.29
stream read하기  (0) 2015.02.18
java Mashalling과 Serialization의 차이  (0) 2015.01.31
Java Serializable : 자바 직렬화  (0) 2015.01.31
thread이야기_02.run()과 start()의 차이  (0) 2014.11.23
Posted by duehd88
,

Marshalling과 Serialization을 유사하다고 한다. 위키피디아에 따르면 파이썬 표준라이브러리에서는 직렬화와 마샬링은 동일하게 간주된다고 한다. 포트란에서도 동일하게 본다. 근데 자바에서는 굳이 구분하는데 뭐가 다를까?

Marshalling은 코드베이스를 기록하지만 직렬화는 하지않는 점이 다르다고 한다. 즉 원격 프로시저를 호출하는 것에서는 유사하지만 다른 목적을 가졌다는 것이다. Marshaling은 원격 프로시저를 호출할때 함수의 parameter, return value들을 전달할 수 있는데 반해 Serialization은 구조화된 데이터를 byte stream과 같은 형식으로 복사하는 것을 의미한다.

이해하기가 어렵다. 쉽게 이야기하면 직렬화는 객체 자체를 복사하는 개념이고 마샬링은 코드베이스를 가져와 만드는 개념이다.

그래서 객체를 이용하지 않는 다른 언어 또는 플랫폼간의 통신할때 주로 Marshaling을 과정을 통한다. 그리고 네트워크나 객체 싱크에는 Serialization을 많이 이용한다.

Posted by duehd88
,

 Java Serializable : 자바 직렬화
  자바는 컴파일 후 생성된 .class파일은 우리가 만든 클래스의 정보를 담고 있다. 이는 class라는 하나의 데이터 타입이라고 볼 수 있다. 이 .class의 바이트가 가상머신에서 우리가 만들었던 클래스로 로딩되고 그 정보를 보고 객체(instanse)를 생성한다. 그리고 그 객체에 맞는 메모리가 할당된다. 아무튼 이 가상머신 내부에 존재한는 객체 메모리를 저장하거나 네트워크로 전송하기 위해서 한 줄로 이어진 바이트의 형태를 만드는 것, 그러니까 바이트 스트림을 만들어내는 것을 객체 직렬화라고 한다. 또한 보안같은 특별한 이유로 특정값을 직렬화에서 제외할 수 있는데 이것은 transient제어자를 붙이면 된다.


  직렬화 방법은 두가지가 있다. Serializable 또는 Externalizable이라는 Interface를 implements하여 구현할 수 있다. 두가지의 차이를 간단히 설명하자면 Serializable는 데이터의 저장과 복구가 자동으로 이루어진다. Externalizable 직렬화 권한은 주지만 데이터의 저장 및 복구 방법을 사용자가 구현해야한다.


 

아래 예제는 예전에 공부하면서 따라했던 코드이다.

 

Serializable예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class SerialObject implements Serializable{
    private String name;
    private String dept;
    private String title;
 
    public SerialObject (String name, String dept, String title){
        this.name = name;
        this.dept = dept;
        this.title = title;
    }
 
    public String toString(){
        return name + ":" + dept + ":" + title;
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
public class SerialObjectTest{
    public static void main(String[] args) throws Exception{
        FileOutputStream fos = new FileOutputStream("object.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
 
        SerialObject so1 = new SerialObject("갑""노동부""부장");
        SerialObject so2 = new SerialObject("을""노동부""신입");
 
        oos.writeObject(so1);
        oos.writeObject(so2);
        oos.close();
 
        FileInputStream fis = new FileInputStream("object.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);
 
        SerialObject rso1 = (SerialObject)ois.readObject();
        SerialObject rso2 = (SerialObject)ois.readObject();
 
        System.out.println(rso1.toString());
        System.out.println(rso2.toString());
        ois.close();
    }
}

 

Externalizable예제

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
public class ExternalObject implements Externalizable{
    private String name;
    private int age;
    private float height;
 
    public ExternalObject(String name, int age, float height){
        this.name = name;
        this.age = age;
        this.height = height;
    }
 
    public void readExternal(ObjectInput oi) throws IOException, ClassNotFoundException{
        name = (String)oi.readObject();
        age = oi.readInt();
        height = oi.readFloat();
    }
 
    public void writeExternal(ObjectOutput oo) throws IOException{
        oo.writeObject(name);
        oo.writeInt(age);
        oo.writeFloat(height);
    }
 
    public String toString(){
        return "이름:"+name+", 나이:"+age+ ", 키:"+height;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ExternalObjectTest{
    public static void main(String[] args) throws IOException, ClassNotFoundException{
        FileOutputStream fos = new FileOutputStream("external.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
 
        ExternalObject so1 = new ExternalObject("갑",43,170.25f);
        ExternalObject so2 = new ExternalObject("을",26,190.01f);
 
        oos.writeObject(so1);
        oos.writeObject(so2);
        oos.close();
 
        FileInputStream fis = new FileInputStream("external.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);
 
        ExternalObject rso1 = (ExternalObject)ois.readObject();
        ExternalObject rso2 = (ExternalObject)ois.readObject();
 
        System.out.println(rso1.toString());
        System.out.println(rso2.toString());
        ois.close();
    }
}

위의 코드들에는 문제가 한가지 있다. serialVersionUID가 없다.

serialVersionUID는 명시적으로 선언해주면 InvalidClassException을 피할 수 있다. 컴파일러마다 다른계산법에 의해 serialVersionUID의 default값이 변화할 수 있기 때문이다. 또 serialVersionUID는 클래스 내부에서만 이용되므로 private 키워드를 붙여주는 것을 권고한다.

Posted by duehd88
,

우선 코드부터

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
public class MainThread{
    public static void main(String[] args){
        Thread mThread=Thread.currentThread();
        printThreadID(mThread.getName()+"-시작");
        
        Thread th1=new Thread(new RunInterface());
        Thread th2=new Thread(new RunInterface());
        Thread th3=new Thread(new RunInterface());
        Thread th4=new Thread(new RunInterface());
        
        th1.run();
        th2.run();
        th3.start();
        th4.start();
        
        printThreadID(mThread.getName()+"-종료");
    }
    
    protected static void printThreadID(String id){
        System.out.println(id);
    }
}
 
class RunInterface implements Runnable{
    @Override
    public void run(){
        Thread mThread=Thread.currentThread();
        MainThread.printThreadID(mThread.getName()+"-시작");
        for(int i=0;i<10;i++){
            MainThread.printThreadID(mThread.getName()+"-"+i);
        }
        MainThread.printThreadID(mThread.getName()+"-종료");
    }
}//RunInterface end
 

실행결과는 해보면 앎.

 

간단히 얘기하자면 각자 thread는 memory에서 stack을 call해서 이용한다. 이때 start()할 경우 개인의 thread를 만들고 개인의 call stack을 이용한다. 하지만 run()할 경우 thread를 만들고 thread를 만든 main thread의 context와 Thread-0,Thread-1의 context가 switching 되어 작업된다. 즉, run() method로 쓰레드를 사용할 경우 main thread의 call stack을 이용한다.

Posted by duehd88
,

하나의 process 내부에도 엄연한 작업 단위가 있다. 이를 thread라고 하고 요즘엔 당연 multi-threading 방식의 programming을 한다.

물론 여러 이슈에 따라서 single-threading방식이 더 유리한 경우도 있다는 거 알아두자!

(예를 들면 Android와 Node-js는 single-thread기반이다.)

 

 runInterface class

1
2
3
4
5
6
7
8
9
10
11
12
public class runInterface implements Runnable{
    @Override
    public void run(){
        Thread mThread=Thread.currentThread();
        System.out.printf("%s-시작\n",mThread.getName());
        for(int i=0;i<50;i++){
            System.out.printf("%s-%d\n",mThread.getName(),i);
        }
        System.out.printf("%s-종료\n",mThread.getName());
    }
}
 

 example class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class example{
    public static void main(String[] args){
        //currentThread() 메서드는 static 메서드이다.
        Thread mThread=Thread.currentThread();
        System.out.printf("%s-시작\n",mThread.getName());
        
        runInterface run=new runInterface();
        
        Thread thread1=new Thread(run);
        Thread thread2=new Thread(run);
        
        thread1.start();
        thread2.start();
        
        System.out.printf("%s-종료\n",mThread.getName());
    }
}
 

 실행해보자!

process가 돌때 main thread가 만들어지고 Thread-0과 Thread-1을 돌린다. 그리고 main thread는 바로 종료된다.

거의 main thread는 Thread-0과 Thread-1을 만들고 start 시켜준뒤 바로 종료 되었지만 Thread-0과 Thread-1을 계속 작업을 하는 것을 알 수 있다.

 

Posted by duehd88
,

자바

1. 자바의 개발도구 JDK는 1995년 5월에 썬 마이크로시스템즈에서 처음 발표했다. 

2. 자바는 좁은 의미로 객체지향 프로그래밍언어이다. 

3. 넓은 의미로 서버와 클라이언트, 모바일, 스마트한 기기등 여러 하드웨어 플랫폼에서 운영될 수 있는 소프트웨어 가상 플랫폼이다.

특징

1. 단순하다.

- 프로그래머가 어려워 하는 포인터를 쓰지않는것이 가장 큰 특징중 하나

2. 객체지향 언어이다.

- 오로지 클래스단위로 객체지향 프로그램 개발해야 한다.

3. 시스템에 독립적이다.

- 한번 만들어진 자바 프로그램은 어느 플랫폼에서나 동일하게 실행된다.

4. 번역언어 이다.

- 실행시 인터프리터가 있다.

- 이게 참 독특한데 소스코드를 컴파일 하여 바이트코드라는 클래스파일을 만들고 JVM에서 인터프리터 식으로 읽어 실행한다.

----------------------------------------------------------------

자, 그럼 JDK는 무엇일까?

개발을 위한 도구와 자바실행환경(JRE)을 제공한다.

그러므로 JRE만 받으면 자바실행은 될지 몰라도

컴파일러인 javac과 기타 도구들이 없어 프로그램 개발이 불가능하다.

개발을 한다면 꼭 JDK를 받자!! 

 

 

  JAVA SE, JAVA EE, JAVA ME, JAVA FX, JAVA DB등등 여러가지가 많이 있는데 특화된 기능에 따라 제공해주는 기술이 있다. 예를 들면 JAVA ME 같은 경우 임베디드장치같이 메모리나 저장용량이 작아야하는 장치를 위한 기술을 제공한다. 하지만 결국 기본은 모두 JAVA SE로부터 시작한다.

Posted by duehd88
,

자동으로 import 하는 단축키

 - Eclipse는 Ctrl + Shift + o(영어키)

 - inteliJ 기반인 Android Studio에서는 Alt + Enter key

Posted by duehd88
,

이 둘의 차이를 망각하는 경우가 있다.

 

둘다 String을 integer로 변환하여 사용하고자 할때 쓴다.

하지만 둘은 다르다.

 

parseInt는 integer를 반환한다.

valueOf는 integer 객체를 반환한다.

 

또 parseInt는 "-"가 같이 들어갈 경우 음수로 인식해준다.

valueOf는 음수를 인식하지 못한다. 또 내부적으로 parseInt를 사용한다.

 

간혹 사람들중 성능차이를 이야기하던데... 성능보다는 용도차이로 구분을 하는게 더 정확한거 같다.

Posted by duehd88
,