잠시 혼자서 안드로이드 개발을 하면서 자바를 만지는 중인데, 애초에 사용했던 언어가 C++ 이다 보니까, vector를 대체 할 것을 찾던 중 List에 대해서 확인하게 되었다. List에 몇가지 종류가 있기는 하는데 디테일 한것은 나중에 하기로 하고, LinkedList 라는 클래스의 실제 사용에 대해서만 포스트 남겨 본다.
List들이 가질 수 있는 것들은 기본 타입(int, double, ...)은 들어 갈 수 없고, 불특정 Object만 들어가게 된다. 원래 테스트로 int 를 하려고 보니까, 안되서 Integer로 테스트ㅋ 각기 테스트는 Integer, String, 자체 클래스로 하였다.
일단 각각의 List를 예쁘게 출력하게끔 만들어는 봤는데... 한꺼번에 합치는 건 잘 모르겠다.
private static void printIntegerList(List<integer> l) { System.out.println("list Size : "+l.size()); for(Object i : l) { System.out.print(i + " "); } System.out.println("\n"); }
private static void printStringList(List<String> l) { System.out.println("list Size : "+l.size()); for(Object i : l) { System.out.print(i + " "); } System.out.println("\n"); }
private static void printMyList(Listl) { System.out.println("list size : "+l.size()); for(Object i : l) { System.out.print(i+" "); } System.out.println("\n"); }
보시면 알겠지만 내부는 다 똑같다. 근대 어떻게 하나의 함수명으로 하는 지 사용법을 영.....;;;
뭐 딱히 중요 한 것은 아니니까 넘어가고...
List<Integer>의 사용법 이다. 아래와 같이 선언하고 사용하면 된다.
List<Integer> listIntegerTest = new LinkedList<Integer>();
C++에서 vector의 넣는 함수처럼 원소 삽입은 add(Object o) 메쏘드를 사용 하면 된다. 아래는 14부터 5까지 차례로 원소로 넣어 보았다.
for(Integer i = 14 ; i >= 5 ; --i) { listIntegerTest.add(i); }
제거는 인덱스로 제거 할 수도 있으며 해당 Object로 제거 할 수도 있다. remove(int idx) 또는 remove(Object o)메쏘드를 사용 하면 된다.
0번째 인덱스를 제거해 보았다.
listIntegerTest.remove(0); // 14제거
remove(..) 함수는 제거되는 인덱스의 원소를 반환한다. 한번 더 0 번째 인덱스를 제거해 보았다. 기존에 14부터 5까지 넣었는데 0번째 인덱스를 두 번째 제거하는 것이므로 13원소가 제거 된다.
// remove 함수는 제거되는 인덱스의 원소를 반환한다. System.out.println("removed element : " + listIntegerTest.remove(0)); // 2제거
하지만 인덱스를 벗어나게 되면 예외처리를 발생시키게 된다. 지금의 예시는 Integer로 하게 되는데, 앞서 add(..)시에는 바로 int가 Integer로 자동 캐스트가 되지만, remove는 두 가지 타입(인덱스 접근시 int, 오브젝트 접근시 Integer의 메쏘드가 별도로 있으므로 벗어나는 인덱스에서는 예외처리를 던지게 된다.
try { // 인덱스를 벗어 났을 경우 // 근대 이게 사실 Interger 10을 제거 하고 싶은 거라면? listIntegerTest.remove(10); } catch(Exception e) { // IndexOutOfBoundsException을 알려주며, 제거 인덱스와 현재 Size를 알려준다. System.out.println(e); }
Object로 원소를 삭제 할 경우에는 boolean 값을 반환한다. 있어서 삭제가 되었다면 true, 없거나 실패했으면 false를 반환(하는데 사실 실패 할 경우는 잘 모르겠다ㅋ)한다.
System.out.println("remove \"10\" object after made Integer \"10\" object"); Integer ten = 10; System.out.println("ten object revmoed success ? " + listIntegerTest.remove(ten)); System.out.println("ten object revmoed success ? " + listIntegerTest.remove(ten));
String 클래스는 문자열에 대한 클래스 이다. 더블쿼터스(")로 묶여있는 문자의 집합이며 무조건 String 객체로 자동 캐스트 시켜주는 듯 싶다.
아래는 List<String> 생성후 "a"부터 "j"까지 순서대로 넣어 보았다.
List<String> listStringTest = new LinkedList<String>(); listStringTest.add("a"); listStringTest.add("b"); listStringTest.add("c"); listStringTest.add("d"); listStringTest.add("e"); listStringTest.add("f"); listStringTest.add("g"); listStringTest.add("h"); listStringTest.add("i"); listStringTest.add("j");
삭제 부분은 위와 같으므로 일단은 단순 제거 해 보았다.
System.out.println("remove 0th index & \"b\" object..."); listStringTest.remove(0); // 인덱스 제거 listStringTest.remove("b"); // 오브젝트 제거
이러한 특정 원소들의 집합체를 사용하는 가장 큰 이유 중에 하나는 정렬! C++의 STL처럼(사실 이런건 자바가 먼저 만든 것으로 알고 있지만 여튼 전 C++유저니까ㅋ) 너무나도 잘 되어있다. 이러한 집합체를 다루는 Collections가 가지고 있는 메쏘드를 가지고 정렬을 할 수 있다.
기본적으로 두가지 방법이 존재 한다. Collections.sort(List<T> l)과 Collections.sort(List<T> l, Comparator <? Super T> c). 전자는 해당 클래스가 가지고 있는 compareTo 라는 메쏘드가 이미 선언이 되어 있는 상태에서 기본적인 오름차순 정렬을 해준다. 후자는 각 클래스가 가지고 있는 맴버변수별로 따로 정렬 방식을 달리 해줘야 할 때 사용 된다. 일단 기본적인 오름차순을 가지고 내림차순으로 바꾸는 정렬은 밑에서 바로 보여주겠다.
Collections.sort(listIntegerTest); // 기본적으로는 오름차순 정렬 printIntegerList(listIntegerTest); // 출력 확인
Collections가 가진 메쏘드 중에 reverse(..) 메쏘드는 List와 같이 순서가 존재하는 집합체를 역으로 설정한다. 오름차순으로 정렬한 후에 거꾸로 하게 되면 자동으로 내림차순!
Collections.reverse(listIntegerTest); // 거꾸로 저장 printIntegerList(listIntegerTest); // 출력 확인
String Class도 마찮가지 방법으로 해 보았다.
Collections.sort(listStringTest); // 기본적으로는 오름차순 정렬 printStringList(listStringTest); // 출력 확인 Collections.reverse(listStringTest); // 거꾸로 저장 printStringList(listStringTest); // 출력 확인
이제 직접 define한 클래스에 대해서 접근해 보자. 사실 이번에 가계부 어플을 만들기 이전에 Java에 대해서도 어느정도 필요한 기본만 슬쩍 보려고 한 것이 이렇게 포스트가 길어졌지만, 나중에 다시 볼 생각 하면서 작성해 보았다.
myDetailCategoryTest 에 대한 클래스는 아래와 같다. Index는 그냥 유니크한 킷값이고 중요한 건 Count이다. 각기 다른 Count에 대해서 정렬이 되어야 하기 때문에 일단은 이것만 두었다. 실제로는 다른 변수들이 여럿 더 있지만 그냥 객체 집합체의 정렬을 테스트 해보려고 만들었다.(하지만 하나의 변수만을 가지고 정렬 할 수도 있으니까 기본 정렬 방식에 대한 부분도 같이 언급)해당 클래스를 만들 때 비교가능한 클래스라고 선언 해주고 해당 메소드인 compareTo(해당클래스 o); 를 구현해주면 된다.(아마 이클립스를 사용하면 빨간줄이 그어지고(클래스 명에) 그곳에 마우스를 올리면 만드는게 나올 듯 싶다.
public class myDetailCategoryTest implements Comparable<myDetailCategoryTest>{ private Integer m_Index; private Integer m_Count; public myDetailCategoryTest(Integer index, Integer count) { // 초기화 m_Index = index; m_Count = count; } public Integer getCount(){ return m_Count; } public Integer getIndex(){ return m_Index; } public String toString() { return m_Index + "(" + m_Count + ")"; } public int compareTo(myDetailCategoryTest other) { if(m_Count > other.getCount()) return 1; else if(m_Count < other.getCount()) return -1; else return 0; } }
하나의 변수만 있을 땐, 실상 이렇게 자세하게 구현할 필요는 없지만, 실제로는 변수가 많으므로 Comparator라는 인터페이스를 구현해야 한다. 이 Comparator는 기본적인 함수로 compare를 생성하게 되는데 이때 필요한 것이 어떤 클래스를 비교하게 되는지 알아야 하기 때문에 초기에 알려줘야 한다.
import java.util.Comparator; public class CompareMyClassCountASC implements Comparator<myDetailCategoryTest>{ public int compare(myDetailCategoryTest o1, myDetailCategoryTest o2) { // Compare 함수를 Collections.sort(..)의 두번째 인자로 넣어준다. // 기본적으로 이 설정은 오름차순 정렬 if(o1.getCount() > o2.getCount()) return 1; else if(o1.getCount() < o2.getCount()) return -1; else return 0; // 애초에 내림차순 정렬을 하고 싶으면 메쏘드를 새로 만들어서 // Collections.sort(..)의 두번째 인자로 넣어주던지, // 현재 이 메쏘드로 정렬을 한후에 Collectors.reverse(..)로 거꾸로 저장 하면 된다. // 두가지 방법 모두 사용 해 보겠다. } }
내림차순 정렬도 따로 만들어 보았다. 실제로는 오름차순하고 reverse 한 것과 별 차이는 없다.
import java.util.Comparator; public class CompareMyClassCountDESC implements Comparator<myDetailCategoryTest>{ public int compare(myDetailCategoryTest o1, myDetailCategoryTest o2) { // 내림차순 정렬 if(o1.getCount() > o2.getCount()) return -1; else if(o1.getCount() < o2.getCount()) return 1; else return 0; } }
일단 모두다 Comparator를 구현한 클래스로 정렬 한 후 출력한 결과이다.
// 오름차순 정렬(별도 비교 클래스 사용) Collections.sort(listMyTest, new CompareMyClassCountASC()); printMyList(listMyTest); // 내림차순 정렬(별도 비교 클래스 사용) Collections.sort(listMyTest, new CompareMyClassCountDESC()); printMyList(listMyTest);
기본 구현한 비교 함수를 통한 정렬과 reverse를 통한 재배치를 한 후 출력한 결과이다.
Collections.sort(listMyTest2); printMyList(listMyTest2); // 원소 역으로 재배치 Collections.reverse(listMyTest2); printMyList(listMyTest2);
이제... 전체 코드 다 합쳐서 이런 모양이 된다. 그냥 사용만 하는 다른 분들도 도움을 받았으면 한다.
import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Random; public class main { public static void main(String[] args) { /**************************************************** * 기본적인 사용 방법 ******************************************************/ //**** Interger Object 사용시 ****/ List<Integer> listIntegerTest = new LinkedList<Integer>(); // listTestObject 에 1부터 10까지 넣는다.(add) for(Integer i = 14 ; i >= 5 ; --i) { listIntegerTest.add(i); } // 전체 출력 확인 printIntegerList(listIntegerTest); // 인덱스로 제거 System.out.println("0th index remove..."); listIntegerTest.remove(0); // 14제거 // remove 함수는 제거되는 인덱스의 원소를 반환한다. System.out.println("removed element : " + listIntegerTest.remove(0)); // 2제거 // 전체 출력 확인 printIntegerList(listIntegerTest); System.out.println("Fire Exception!!!"); try { // 인덱스를 벗어 났을 경우 // 근대 이게 사실 Interger 10을 제거 하고 싶은 거라면? listIntegerTest.remove(10); } catch(Exception e) { // IndexOutOfBoundsException을 알려주며, 제거 인덱스와 현재 Size를 알려준다. System.out.println(e); } // remove는 boolean을 반환한다. // Integer 10 객체를 만들어서 삭제 System.out.println("remove \"10\" object after made Integer \"10\" object"); Integer ten = 10; System.out.println("ten object revmoed success ? " + listIntegerTest.remove(ten)); System.out.println("ten object revmoed success ? " + listIntegerTest.remove(ten)); // 전체 출력 확인 printIntegerList(listIntegerTest); //**** String Class 사용시 ****// List<String> listStringTest = new LinkedList<String>(); listStringTest.add("a"); listStringTest.add("b"); listStringTest.add("c"); listStringTest.add("d"); listStringTest.add("e"); listStringTest.add("f"); listStringTest.add("g"); listStringTest.add("h"); listStringTest.add("i"); listStringTest.add("j"); // 전체 출력 확인 printStringList(listStringTest); // 제거 System.out.println("remove 0th index & \"b\" object..."); listStringTest.remove(0); // 인덱스 제거 listStringTest.remove("b"); // 오브젝트 제거 // 전체 출력 확인 printStringList(listStringTest); /**************************************************** * 기존에 이미 정의 되어 있는 객체의 정렬 ******************************************************/ // Integer Object 정렬 System.out.println("Integer object list sort & print..."); Collections.sort(listIntegerTest); // 기본적으로는 오름차순 정렬 printIntegerList(listIntegerTest); // 출력 확인 Collections.reverse(listIntegerTest); // 거꾸로 저장 printIntegerList(listIntegerTest); // 출력 확인 // String Object 정렬 System.out.println("String object list sort & print..."); Collections.sort(listStringTest); // 기본적으로는 오름차순 정렬 printStringList(listStringTest); // 출력 확인 Collections.reverse(listStringTest); // 거꾸로 저장 printStringList(listStringTest); // 출력 확인 /**************************************************** * 사용자 지정 클래스 사용 ******************************************************/ List<myDetailCategoryTest> listMyTest = new LinkedList<myDetailCategoryTest>(); List<myDetailCategoryTest> listMyTest2 = new LinkedList<myDetailCategoryTest>(); Random oRandom = new Random(); for(int i = 1 ; i <= 10 ; ++i) { myDetailCategoryTest elem = new myDetailCategoryTest(i, oRandom.nextInt(10)+1); listMyTest .add(elem); listMyTest2.add(elem); } System.out.println("When use implements class method..."); printMyList(listMyTest); // 오름차순 정렬(별도 비교 클래스 사용) Collections.sort(listMyTest, new CompareMyClassCountASC()); printMyList(listMyTest); // 내림차순 정렬(별도 비교 클래스 사용) Collections.sort(listMyTest, new CompareMyClassCountDESC()); printMyList(listMyTest); // 오름차순 정렬 System.out.println("When use default method..."); printMyList(listMyTest2); Collections.sort(listMyTest2); printMyList(listMyTest2); // 원소 역으로 재배치 Collections.reverse(listMyTest2); printMyList(listMyTest2); } private static void printIntegerList(List<Integer> l) { System.out.println("list Size : "+l.size()); for(Object i : l) { System.out.print(i + " "); } System.out.println("\n"); } private static void printStringList(List<String> l) { System.out.println("list Size : "+l.size()); for(Object i : l) { System.out.print(i + " "); } System.out.println("\n"); } private static void printMyList(List<myDetailCategoryTest> l) { System.out.println("list size : "+l.size()); for(Object i : l) { System.out.print(i+" "); } System.out.println("\n"); } }>
'Programming > Java' 카테고리의 다른 글
난수 사용 하기 (0) | 2012.07.24 |
---|