2012년 11월 12일 월요일

String split() 사용

1. 일반적으로 생각하는 split() 함수 사용

 > 아래와 같이 String 을 split() 함수를 이용해 나눌 수 있다.

String line = "a,b,c,d,e,f";
String[] result = line.split(",");

결과:
result ==> [a, b, c, d, e, f]


2. delimiter 사이에 빈 문자 처리

 > 아래와 같은 경우 빈 string 도 결과 배열에 포함한다.

String line = "a,,c,d,e,f";
String[] result = line.split(",");

결과:
result ==> [a, , c, d, e, f]

 > 아래와 같은 경우 빈 string 을 결과 배열에 포함하지 않는다.

String line = "a,,c,d,e,f";
String[] result = line.split("(,+)");

결과:
result ==> [a, c, d, e, f]

설명:
정규 표현 (,+) 의 의미는 , 이 하나 이상을 표현한다.
결국 연달아 , 이 반복되는 경우 하나의 delimiter 로 인식한다.

Regex 참고: http://moonlighting.tistory.com/52

2012년 10월 4일 목요일

Array 정렬

Arrays.sort() 함수를 이용해 배열을 정렬할 수 있다.

Comparator 를 구현하여 정렬 방식을 조절할 수 있다.

예) 파일 목록을 디렉토리, 파일 순으로 정렬하면서 알파벳 순으로 정렬하는 코드

File[] files = file.listFiles();

Arrays.sort(files, new Comparator<File>() {
public int compare(File f1, File f2) {
boolean d1 = f1.isDirectory();
boolean d2 = f2.isDirectory();
if (d1 && !d2) {
return -1;
} else if (!d1 && d2) {
return 1;
} else {
return f1.getName().toUpperCase().compareTo(f2.getName().toUpperCase());
}
}
});

정리) compare() 함수에 -1 을 리턴하면 앞의 값을 앞으로 1 을 리턴하면 뒤의 값을 앞으로 0 을 리턴하면 변경 없이 정렬이 된다.

2012년 9월 13일 목요일

Pool 예제

솔직히 Pool 에 대해 제가 정확히 이해했는지 자신 없습니다. 아래 내용은 제 사견입니다.

Pool 은 미리 사용하려는 양 만큼의 버퍼를 할당해 놓고 객체를 사용하고 사용한 객체는 다시 버퍼에 넣고 재활용하는 방식의 방법입니다.

이런 방식의 장점으로는 버퍼를 재활용함으로 인해 객체 할당 및 제거에 드는 시간을 없앨 수 있다는 점이 있겠습니다.

Pool.java
 - queue 가 두개 필요합니다. 유휴 버퍼와 사용 가능 버퍼로 나눕니다.
 - 유휴 버퍼는 미리 빈 객체들로 원하는 갯수 만큼 채워 넣습니다.
 - 사용 가능 버퍼에는 유휴 버퍼에서 얻은 사용 객체로 하나씩 채워지게 됩니다.
 - 사용 가능 버퍼를 다 사용하고 나면 다시 유휴 버퍼로 옮겨 넣음으로써 나중에 다시 사용 가능하게 됩니다.

소스 코드 :
package pool.test;

import java.util.concurrent.LinkedBlockingQueue;

/**
 *
 * @param <T>
 */
public class Pool<T> {
    
    private LinkedBlockingQueue<T> free = new LinkedBlockingQueue<T>();
    private LinkedBlockingQueue<T> work = new LinkedBlockingQueue<T>();
    
    /**
     * 
     * @param creator
     * @param count
     */
    public Pool(PoolObjectCreator<T> creator, int count) {
        for (int i = 0;i < count; i++) {
            free.add(creator.create());
        }
    }
    
    /**
     * 
     * @return
     */
    public final T acquire() {
        return free.size() > 0 ? free.remove() : null;
    }
    
    /**
     * 
     * @param item
     */
    public final void enqueue(T item) {
        work.add(item);
    }
    
    /**
     * 
     * @return
     */
    public final T dequeue() {
        return work.size() > 0 ? work.remove() : null;
    }
    
    /**
     * 
     * @param item
     */
    public final void release(T item) {
        free.add(item);
    }
    
    /**
     *
     * @param <T>
     */
    public static interface PoolObjectCreator<T> {
        public T create();
    }
}

아래 내용은 Pool 사용 예제 입니다.
 - Producer 스레드에서는 1초 마다 pool 에 데이터를 넣습니다.
 - Consumer 스레드에서는 pool 에서 데이터를 받아서 화면에 값을 출력합니다.

Main.java :
package pool.test;

import java.io.BufferedReader;
import java.io.InputStreamReader;

/**
 *
 */
public class Main {
    
    private Consumer consumer;
    private Producer producer;
    
    /**
     * 
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        
        Main main = new Main();
        main.start();
        
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        reader.readLine();
        
        main.stop();
        
        System.out.println("Done");
    }
    
    /**
     * 
     */
    public void start() {
        
        Pool<Container> pool = new Pool<Container>(new Pool.PoolObjectCreator<Container>() {
            @Override
            public Container create() {
                return new Container();
            }
        } , 10);
        
        
        producer = new Producer(pool);
        consumer = new Consumer(pool);
        
        producer.start();
        consumer.start();
    }
    
    /**
     * 
     */
    public void stop() {
        
        producer.interrupt();
        consumer.interrupt();
        
    }
    
    /**
     * 
     */
    public class Container {
        public int x;
    }
    
    
    
    /**
     *
     */
    public class Producer extends Thread {
        
        private Pool<Container> pool;
        
        public Producer(Pool<Container> pool) {
            this.pool = pool;
        }

        @Override
        public void run() {
            super.run();
            
            try {
                
                System.out.println("Producer :: start");
                
                int count = 0;
                
                Container container = null;
                while (!Thread.interrupted()) {
                    
                    if ((container = pool.acquire()) != null) {
                        
                        container.x = count++;
                        
                        pool.enqueue(container);
                        
                        Thread.sleep(1000);
                        
                    } else {
                        Thread.sleep(10);
                    }
                }
                
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                System.out.println("Producer :: done");
            }
        }
    }
    
    
    /**
     *
     */
    public class Consumer extends Thread {
        
        private Pool<Container> pool;
        
        public Consumer(Pool<Container> pool) {
            this.pool = pool;
        }

        @Override
        public void run() {
            super.run();
            
            try {
                
                System.out.println("Consumer :: start");
                
                Container container = null;
                while (!Thread.interrupted()) {
                    
                    if ((container = pool.dequeue()) != null) {
                        
                        System.out.printf("x : %d\n", container.x);
                        
                        pool.release(container);
                        
                    } else {
                        Thread.sleep(10);
                    }
                }
                
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                System.out.println("Consumer :: done");
            }
        }
    }
    
}