■ Collection : 오브젝트 집합을 나타내는 가장 기본적인 인터페이스
   □ Set : 중복 요소 없는 오브젝트 집합
      ○ SortedSet : 요소가 자동 올림순으로 정렬된다.
                            삽입되는 요소는 Comparable 인터페이스 속성을 갖고 있지만
                            지정된 Comparator에 의해 받아들여진다.
   □ List : 순서있는 오브젝트 집합, 중복허가, 리스트내의 특정위치에 요소를 넣을 수 있다.
               유저는 위치(인덱스)를 지정하여 각요소에 접근할 수 있다.

■ Map : 키-값으로 나타내는 오브젝트 집합. 키는 중복될 수 없다.
   □ SortedMap : 요소가 키로서 자동 올림순 정렬되는 Map.
                          삽입된 키는 Comparable 인터페이스 속성을 갖고 있지만
                          지정된 Comparator에 의해 받아들여진다.

구분 해쉬테이블 가변배열 밸런스트리 링크리스트 해쉬테이블&링크리스트
Set HashSet TreeSet LinkedHashSet
List ArrayList LinkedList
Map HashMap TreeMap LinkedHashMap

HashSet   : HashMap 인터페이스를 기본으로 Set인터페이스를 구현한 것. 순서를 보장할 수 없다.

TreeSet    : TreeMap 인터페이스를 기본으로 Set인터페이스를 구현한 것. 올림순으로 소트된다.

LinkedHashSet : 삽입된 순서를 기억한다.
                          같은 요소를 다시 삽입하면 이전 순서를 그대로 기억한다.

ArrayList   : List 인터페이스 속성을 갖고 배열크기를 변경할 수 있다.
                  배열크기를 조작하는 메소드를 제공한다.

LinkedList : 리스트의 처음과 마지막 요소를 삽입,삭제할 수 있다. 
                  그 관련 메소드 제공.
                  동기화되어 있지 않다는 것을 제외하면 Vector와 같다.

HashMap : 동기화되어 있지않다는 것과 Null을 허용한다는 것 이외에는 HashTable과 같다.

TreeMap  : Red-Black Tree. 키의 올림순으로 소트된다.
                  LinkedHashMap : 키가 맵에 삽입된 순서를 기억한다. 
                  같은 키로 삽입해도 이전의 순서를 기억한다.


■HashSet,TreeSet,LinkedHashSet 비교
중복요소없는 오브젝트 집합을 관리하는 클래스에는 HashSet,TreeSet,LinkedHashSet가 있다.
Set기능만 필요한 경우에는 HashSet.
요소를 올림차순으로 정렬하는 경우에는 TreeSet.
요소의 삽입순서를 기억할 필요가 있을 때에는 LinkedHashSet.

■ArrayList와 LinkedList
순서있는 오브젝트 집합을 관리하는 클래스로는 ArrayList와 LinkedList가 있다.

구분 인덱스 엑세스 Iterator 엑세스 추가 삽입 삭제
ArrayList 느림 느림
LinkedList 느림

ArrayList는 인덱스에 의한 랜덤엑세스 성능이 좋지만
요소의 삽입, 삭제에는 좋지않다.
LinkedList는 거꾸로 요소의 삽입, 삭제에는 성능이 좋지만
인덱스에 의한 랜덤엑세스는 좋지 않다.

■HashMap, TreeMap, LinkedHashMap 
키-값 관계로 맵핑하는 경우에 사용하는 클래스에는 HashMap, TreeMap, LinkedHashMap이 있다.
Map 기능만 필요한 경우는 HashMap
키를 올림차순으로 소트할 필요가 있을 때는 TreeMap
키의 삽입순서를 기억할 필요가 있을 때에는 LinkedHashMap

■Set Class Test

import java.util.*;

public class SetClassTest {
  public static void main(String[] args) {
    try {
      // HashSet
      Set hashSet = new HashSet();
      addData(hashSet);
      System.out.println("HashSet : " + hashSet);

      // TreeSet
      Set treeSet = new TreeSet();
      addData(treeSet);
      System.out.println("TreeSet : " + treeSet);

      // LinkedHashSet
      Set linkedHashSet = new LinkedHashSet();
      addData(linkedHashSet);
      System.out.println("LinkedHashSet : " + linkedHashSet);

    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  static void addData(Set set) {
    for (int i = 10;i >= 1;i--) {
      set.add(new Integer(i));
    }
  }
}

결과 :

   HashSet : [2,4,8,9,6,1,3,7,10,5]

   TreeSet : [1,2,3,4,5,6,7,8,9,10]

   LinkedHashSet : [10,9,8,7,6,5,4,3,2,1]

 

■List Class Test

import java.util.*;

public class ListClassTest {
  public static void main(String[] args) {
    try {
      long start, end;
      /** 추가 **/
      // ArrayList
      List arrayList = new ArrayList();
      start = System.currentTimeMillis();
      addData(arrayList);
      end = System.currentTimeMillis();
      System.out.println("ArrayList 추가 : " + (end - start));

      // LinkedList
      List linkedList = new LinkedList();
      start = System.currentTimeMillis();
      addData(linkedList);
      end = System.currentTimeMillis();
      System.out.println("LinkedList 추가 : " + (end - start));

      /** 삭제 **/
      // ArrayList
      start = System.currentTimeMillis();
      removeData(arrayList);
      end = System.currentTimeMillis();
      System.out.println("ArrayList 삭제 : " + (end - start));

      // LinkedList
      start = System.currentTimeMillis();
      removeData(linkedList);
      end = System.currentTimeMillis();
      System.out.println("LinkedList 삭제 : " + (end - start));

      /** 삽입 **/
      // ArrayList
      start = System.currentTimeMillis();
      insertData(arrayList);
      end = System.currentTimeMillis();
      System.out.println("ArrayList 삽입 : " + (end - start));

      // LinkedList
      start = System.currentTimeMillis();
      insertData(linkedList);
      end = System.currentTimeMillis();
      System.out.println("LinkedList 삽입 : " + (end - start));


      /**  인덱스 접근 **/
      // ArrayList
      start = System.currentTimeMillis();
      indexAccess(arrayList);
      end = System.currentTimeMillis();
      System.out.println("ArrayList 인덱스 접근 : " + (end - start));

      // LinkedList
      start = System.currentTimeMillis();
      indexAccess(linkedList);
      end = System.currentTimeMillis();
      System.out.println("LinkedList 인덱스 접근 : " + (end - start));

      /** Iterator 로 접근 **/
      // ArrayList
      start = System.currentTimeMillis();
      iteratorAccess(arrayList);
      end = System.currentTimeMillis();
      System.out.println("ArrayList Iterator로 접근 : " + (end - start));

      // LinkedList
      start = System.currentTimeMillis();
      iteratorAccess(linkedList);
      end = System.currentTimeMillis();
      System.out.println("LinkedList Iterator로 접근 : " + (end - start));

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  static void addData(List list) {
    for (int i=1;i<100000;i++) {
      list.add(new Integer(i));
    }
  }
  static void removeData(List list) {
    while(!list.isEmpty()) {
      list.remove(0);
    }
  }
  static void insertData(List list) {
    for (int i=1;i<100000;i++) {
      list.add(0 , new Integer(i));
    }
  }

  static void indexAccess(List list) {
    int size = list.size();
    for (int i=0;i<size;i++) {
      Integer integer = (Integer)list.get(i);
    }
  }
  static void iteratorAccess(List list) {
    Iterator iterator = list.iterator();
    while (iterator.hasNext()) {
      Integer integer = (Integer)iterator.next();
    }
  }
}

결과 :

  ArrayList 추가 : 451

  LinkedList 추가 : 230

  ArrayList 삭제 : 45315

  LinkedList 삭제 : 20

  ArrayList 삽입 : 45416

  LinkedList 삽입 : 170

  ArrayList 인덱스로 접근 : 0

  LinkedList 인덱스로 접근 : 231473

  ArrayList Iterator로 접근 : 60

  LinkedList Iterator로 접근 : 50

 

■Map Class Test

import java.util.*;

public class MapClassTest {
  public static void main(String[] args) {
    try {
      // HashMap
      Map hashMap = new HashMap();
      putData(hashMap);
      System.out.println("HashMap : " + hashMap);

      // TreeMap
      Map treeMap = new TreeMap();
      putData(treeMap);
      System.out.println("TreeMap : " + treeMap);

      // LinkedHashMap
      Map linkedHashMap = new LinkedHashMap();
      putData(linkedHashMap);
      System.out.println("LinkedHashMap : " + linkedHashMap);

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  static void putData(Map map) {
    map.put("5" , "Five");
    map.put("4" , "Four");
    map.put("3" , "Three");
    map.put("2" , "Two");
    map.put("1" , "One");
  }
}

결과 :

HashMap : {3=Three, 5=Five, 2=Two, 4=Four, 1=One}

TreeMap : {1=One, 2=Two, 3=Three, 4=Four, 5=Five}

LinkedHashMap : {5=Five, 4=Four, 3=Three, 2=Two, 1=One}

출처 : 
http://dojeun.egloos.com

 

'Java' 카테고리의 다른 글

ArrayIndexOutOfBoundsException  (0) 2011.07.13
우선순위 큐(Priority Queue)와 힙(Heap)  (0) 2011.05.02
rivate int dipToInt(float number) {

    int num = (int) TypedValue.applyDimension(

                TypedValue.COMPLEX_UNIT_DIP, number, 

                context.getResources().getDisplayMetrics());

    return num;

'안드로이드' 카테고리의 다른 글

Thread 우선순위 설정.  (0) 2011.05.03
Looper  (0) 2011.05.03
[Service] onStartCommand  (0) 2011.04.06
Android에서 alarm List의 Item들이 무한으로 재생되는 경우  (0) 2011.04.04
ForeGround Service  (0) 2011.04.04

출처 : http://blog.naver.com/PostView.nhn?blogId=huewu&logNo=110081442947&redirect=Dlog&widgetTypeCall=true
 

원래 하나의 포스트로 끝마치려고 했지만... 글이 조금 길어지는 경향이 있어서 두 개로 나누어 포스트 합니다. 첫번째 글에서 바로 뒤이어 Service 의 라이프 사이클 변화에 관한 내용을 번역합니다.


Service lifecycle changes

 Service 들이 필요하지 않은 경우에도 불구하고, 자신을 포그라운드 프로세스로 설정하는 문제를 제외하고도,  백그라운드에서 너무 많은 수의 Service 들이 돌아감에 따라, 각각의 Service 들이 한정된 메모리 자원을 차지하게 위해 서로 경쟁하게 되면 또 다른 문제가 발생할 수 있다. 안드로이드 플랫폼과 Service 간의 상호 작용 과정에서, 특정 어플리케이션이 코드상으로는 별다른 문제 없이 작성된 경우에도, Service 가 정상 종료되지 않고 백그라운드에 남아있을 수 있다. 예를 들어 다음과 같은 상황이다.
  1. Application 이 StartService 를 호출 한다.

  2. Service 의 onCreate, onStart() 함수가 호출 되고, 특정한 작업을 수행하기 위해 백그라운드 스레드가 생성된다.

  3. 시스템이 메모리 부족으로 인해 현재 작동중인 서비스를 강제로 종료 한다.

  4. 잠시 후에, 메모리 상황이 호전되어 Service 가 재시작한다. 이 때, Service 의 onCreate 함수는 호출 되지만, onStart 는 호출 되지 않는다. (startService 는 호출 되지 않았음으로..)

 
 결국, Service 는 생성된 채로 남아있게 된다. Service 는 어떠한 일을 수행 하지도 않으며 (무슨 일을 수행해야할 지 알 수 없음으로...), 어떤 시점에 종료되어야 하는지도 알 수 없다.

 이러한 문제를 해결하기 위해 안드로이드 2.0 에서 Service 의 onStart() 는 더이상 사용되지 않는다. (이전 버전과의 호환성 문제때문에 작동 자체는 하지만...) 대신 Service.onStartCommand() 콜백이 사용된다. 이 콜백 함수는 시스템이 Service 를 좀 더 잘 관리 할 수 있도록 해주는데, 기존 API 와는 달리  onStartCommand() 는 결과값을 반환한다. 안드로이드 플랫폼은 이 결과값을 기반으로 만일 작동중인 서비스가 강제로 종료될 경우, 어떠한 일을 수행해야 하는지 판단한다.
  • START_STICKY  는 기본적으로 이전과 동일하게 작동한다. 이전과의 차이점은 다음과 같다.  기존에 프로세스가 강제 종료된 후 Service 가 재 시작 될 때, onStart() 콜백이 호출 되지 않았지만, START_STICKY 형태로 호출된 Service 는 null Intent 가 담긴 onStartCommand() 콜백 함수가 호출된다. 이 모드를 사용하는 Service 는 null Intent 로 onStartCommand() 콜백 함수가 호출되는 경우를 주의깊게 처리해야 한다. 
  • START_NOT_STICKY 모드로 시작된 Service는  안드로이드 플랫폼에 의해 프로세스가 강제로 종료되는 경우, 다시 시작되지 않고 종료된 상태로 남게된다. 이러한 방식은 특정 Intent 로 주어진 명령을 수행하는 동안에만 Service 가 실행되면 되는 경우에 적당하다 예를 들어, 매15분마다 네트워크 상태를 체크하기 위해 실행되는 Service 를 생각해 보면, 만일 이 Service 가 작업도중 강제로 종료될 경우, 이 Service 는 재시작하기 보다는 정지된 상태로 남겨두고, 15분 후에 새롭게 시작되도록 하는 것이 최선이다. 
  • START_REDELIVER_INTENT  는 START_NOT_STICKY 와 유사하다. 단, 프로세스가 강제로 종료되는 경우 (stopSelf() 가 호출 되기 전에 종료되는 경우), Intent 가 다시 전달 되어 Service 가 재시작 한다.  (단, 여러차례 시도한 후에도, 작업이 종료되지 않으면, Service 는 재시작되지 않는다.) 이 모드는 전달받은 명령을 반드시 수행해야 하는 Service 에 유용하다. 
 기존에 존재하는 어플리케이션과의 호환성을 위해서, 이전 버전을 기준으로 제작된 어플리케이션은  START_STICKY_COMPATIBILITY 모드로 작동한다.  (null intent 를 보내지 않고 기존과 동일하게 작동). 단 API 버전 5  이상을 기준으로 작성된 어플리케이션들은 기본적으로 START_STICKY 모드로 작동 하며, 개발자는 반드시 onStart() 나 onStartCommand() 가 null intent 를 가지고 호출되는 경우를 염두해 두어야 한다. 

 개발자들은 아래에 제시된 코드를 활용하여, 손쉽게 이전 버전과 새로운 버전 양쪽 모두에서 작동하는 Service 를 구현할 수 있다. 

    // This is the old onStart method that will be called on the pre-2.0
    // platform.  On 2.0 or later we override onStartCommand() so this
    // method will not be called.
    @Override
    public void onStart(Intent intent, int startId) {
        handleStart(intent, startId);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        handleStart(intent, startId);
        return START_NOT_STICKY;
    }

    void handleStart(Intent intent, int startId) {
        // do work


New "running services" user interface

 * 이 후 이어지는 내용은 새롭게 추가된 Running Service 를 확인 할 수 있는 UI 어플리케이션에 관한 내용이라 대충 대충 건너 띄도록 하겠습니다.

 안드로이드 2.0 부터는 새롭게 "Running Services" Activity 가 어플리케이션 세팅에 추가 되었다. 사용자는 목록에 표시된 Service 를 터치해서 종료할 수 있다.

 화면 하단부에는 현재 시스템의 메모리 상황에 대한 정보가 표시된다. 

  • Avail: 38MB+114MB in 25 은 현재 38MB 의 공간이 바로 사용가능하며, 114MB 의 메모리 공간은 언제든지 종료시킬 수 있는 25개의 백그라운드 프로세스에 의해 점유되고 있음을 알려준다. 
  • Other: 32MB in 3 은 현재 3개의 임의로 종료되서는 않되는 포그라운드 프로세스에 의해 32MB 의 공간이 사용되고 있음을 알려준다. 
 대부분의 사용자들에게 이 새로운 UI 는 기존의 Task Killer 어플리케이션에 비해 사용하기 편리하며, 강제로 Service 를 종료시키는 것이 아니기 때문에 문제를 일으킬 소지가 훨씬 적다. 

 개발자들에게는 자신이 작성한 어플리케이션이 잘 작동하는지 (특히 Service 관리라는 측면에서) 확인 할 수 있게 해주는 유용한 툴이 될 수있다. 또한 어플리케이션이 구동한 Service 가 사용자에 의해 어느시점에서든지 종료 할 수 있다는 점을 염두해 두어야 한다. 안드로이드의 Service 는 매우 강력한 도구이지만, 어플리케이션 개발자들이 전체 폰의 성능에 큰 악영향을 끼칠 수 있는 문제를 가장 많이 일으키는 도구이기도 한다. 

'안드로이드' 카테고리의 다른 글

Looper  (0) 2011.05.03
DIP를 px로 변환하기  (0) 2011.04.21
Android에서 alarm List의 Item들이 무한으로 재생되는 경우  (0) 2011.04.04
ForeGround Service  (0) 2011.04.04
Thread  (0) 2011.03.24

+ Recent posts