JAVA Study

이중데이터 두번에 걸른 정렬방법

85chong 2019. 1. 10. 11:55
728x90
반응형
SMALL

이중데이터로 2차배열을 예로 들겠다.

 China  4
Bangladesh 9999
Korea 1
Thailand 3
Russia 3
Nepal 9999
Canada 9999
India 9999
Uzbekistan 2
Usa 2
위의 데이터로 1차로 숫자를 정렬하고, 그 정렬된 데이터를 가지고, 다시 2차로 알파벳 순으로 정렬해야하는 
상황을 가정해 보았을때의 나만의 방법을 기록하려함.
(! 비비꼬임 주의)

위와 같은 데이터를 1차 숫자 오름차순 정렬
1차 숫자 오름차순 정렬 결과값 : 
 Korea  1
Uzbekistan 2
Usa 2
Thailand 3
Russia 3
China 4
Bangladesh 9999
Nepal 9999
Canada 9999
India 9999

위의 데이터를 2차 알파벳 오름차순 정렬

2차 알파벳 오름차순 정렬 최종 결과값 : 

Korea
Usa
Uzbekistan
Russia
Thailand
China
Bangladesh
Canada
Nepal
India


<전체코드 : >

public class MainActivity extends Activity {


ArrayList<String> mparent_arrlist = new ArrayList<>();
ArrayList<String> mchild_arrlist = new ArrayList<>();
ArrayList<ObjData> list = new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


// 임시 데이터2
list.add(new ObjData("China", 4));
list.add(new ObjData("Bangladesh", 9999));
list.add(new ObjData("Korea", 1));
list.add(new ObjData("Thailand", 3));
list.add(new ObjData("Russia", 3));
list.add(new ObjData("Nepal", 9999));
list.add(new ObjData("Canada", 9999));
list.add(new ObjData("India", 9999));
list.add(new ObjData("Uzbekistan", 2));
list.add(new ObjData("Usa", 2));

Log.d("yck", "========== 최초 데이터 =============");
for (int i = 0; i < list.size(); i++) {
Log.d("yck", "mparent_arrlist[" + i + "] : " + list.get(i).str+" " + list.get(i).val);
}

// 1차 val 기준으로 숫자 순서대로 정렬
// 방식 : 리스트 값을 별도의 클래스를 이용하여 데이터를 가져오고 그 데이터를 comparator 를
// 이용해서 val 기준으로 정렬해서 리턴받는 방식
Collections.sort(list, new Comparator<ObjData>() {
@Override
public int compare(ObjData o1, ObjData o2) {
return o1.val - o2.val;
}
});



Log.d("yck", "========== 1차 정렬 데이터 =============");
for (int i = 0; i < list.size(); i++) {
Log.d("yck", "mparent_arrlist[" + i + "] : " + list.get(i).str+" " + list.get(i).val);
}

// 2차 str 기준으로 알파벳 순서대로 정렬
// 방식 : val 을 그룹으로 생각하고, str 하나씩 map 에 저장하다가 해당 그룹이 끝나는순간,
// 직전에 저장해놓은 그룹을 알파벳 순으로 정렬하고 그 정렬된 리스트를
// 하나의 대표 Arraylist 로 추가함, 이런 방식을 나머지 그룹이 끝날때 까지
// 대표 Arraylist 에 계속 추가하는 방식
HashMap<String, String> hm = new HashMap<>();
int in_check = (list.get(0).val);
int in_addArray = 0;

for (int i = 0; i < list.size(); i++) {

if (in_check != list.get(i).val) {

AddDataForParentArrayList(hm);
// 새로 등장한 그룹으로 다음 값 받기위한 초기화
in_check = list.get(i).val;
// 새로운 그룹을 처리하기 위한 초기화
mchild_arrlist.clear();
hm.clear();
in_addArray = 0;
}
// list사이즈 조건때문에 1개의 데이터가 남기때문에 마지막 데이터는 바로 추가해주면됨
if (i == list.size() - 1) {
AddDataForParentArrayList(hm);
mparent_arrlist.add(list.get(i).str);
}
hm.put("hm_" + in_addArray, list.get(i).str);
in_addArray++;
}

Log.d("yck", "========== 최종 정렬 =============");
for (int i = 0; i < mparent_arrlist.size(); i++) {
Log.d("yck", "mparent_arrlist[" + i + "] : " + mparent_arrlist.get(i));
}
}




public void AddDataForParentArrayList(HashMap<String, String> hm){
// 새로운 그룹이 검색되면 직전까지 저장했던 map 데이터를 하청 Arraylist 에 임시저장
for (int j = 0; j < hm.size(); j++) {
mchild_arrlist.add(hm.get("hm_" + j));
}

// 그룹에 대한 2차 알파벳순으로 정렬하기
Collections.sort(mchild_arrlist);

// 대표 Arraylist 에 추가하기
for (int k = 0; k < mchild_arrlist.size(); k++) {
mparent_arrlist.add(mchild_arrlist.get(k));
}
}


}


class ObjData {
String str;
int val;

public ObjData(String str, int val) {
this.str = str;
this.val = val;
}
}

위의 방법은 다소 복잡하고 비비꼬인 코드이다. 짜고 나니 공부를 열심히 해야겟다고 생각했다 T  .  T

아래의 방법은 지인찬스?로 풀어낸 코드이다.

<전체코드 2 : >


public class SecondActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Gavin_s_Sort();
}


private void Gavin_s_Sort() {
List<Mto> mtoList = Arrays.asList(
new Mto("China",4),
new Mto("Bangladesh",99),
new Mto("Korea",1),
new Mto("Thailand",3),
new Mto("Russia",3),
new Mto( "Nepal",99),
new Mto("Canada",99),
new Mto( "India",99),
new Mto( "Uzbekistan",2),
new Mto("Usa",2));

//TreeMap을 사용하면 데이터를 무작위로 넣었어도 key 값을 기준으로 기본 올림차순으로 정렬되어진다.
Map<Integer, List<Mto>> map = new TreeMap<>();

for (Mto m : mtoList) {
int key = m.getVal();
/*
val 값이 위에 저장한 map 에 해당키와 같은 값일때, 해당 list 에 추가해준다. ex_) List<str,val> 이형식으로 같은
val(map의 key값)의 list 에 붙게된다.
*/
if (map.containsKey(key)) {
List<Mto> list = map.get(key);
list.add(m);
} else {
//val 값이 새로운값이거나,다른값일때 List<Mto> list 를 생성해서 val ,str 값을 list 에 넣어주고
List<Mto> list = new ArrayList<>();
list.add(m);
//넣어준 list 값을 통째로, 새로 생성된 map 에 key=val 을넣어서 Map<val, List<str,val>> 형식으로 저장시켜준다
map.put(key, list);
}
}

// 최종 2차 과정을 위한 List 를 생성해준다.
List<Mto> resultList = new ArrayList<>();

//TreeMap 은 기본적으로 키값 오름차순 정렬되어 있으므
//Iterator 를 사용해서 list 의 모든값 가져온다.
Iterator<Integer> iterators = map.keySet().iterator();

while (iterators.hasNext()) {
List<Mto> tmpList = map.get(iterators.next());
// Collections.sort(..... 를 이용해서 위의값을 str 기준으로 올림차순으로 정렬하여 tmpList 에 최종적으로 담아준다.
Collections.sort(tmpList, new Comparator<Mto>() {
@Override
public int compare(Mto o1, Mto o2) {
return o1.getStr().compareToIgnoreCase(o2.getStr());
}
});
//최종적인 결과의 tmpList를 최종 2차 결과값을 담을 result List 에 담아주면 위와 같은 2차 최종결과값이 나온다.
resultList.addAll(tmpList);
}

}
}


class Mto {
int val;
String str;

public Mto(String str,int val) {
this.str = str;
this.val = val;
}

public int getVal() {
return val;
}

public void setVal(int val) {
this.val = val;
}

public String getStr() {
return str;
}

public void setStr(String str) {
this.str = str;
}
}

결과값은 같다. 하지만 내코드와 다르게 해당 알파벳과 숫자가 같이 정렬되어 들어가있다. 내 코드같은 경우는

알파벳만 리스트에 넣어서 정렬했기 때문에 해당 알파벳의 숫자 값을 가져오기 위해선 별도의 코드를 작성해야하는 불편함이있다.

그리고 위의 코드는 가변적 응용성이 좋다. 하지만 내 코드는 가변적 응용성이 좋지않다. 예로 위의 임시데이터의 앞뒤 위치를 바꾸면

내 코드는 수정을 해줘야만 결과값이 나온다.


Java 의 기초와 자료구에 대해 좀 더 집중해서 공부해야겠다.


-끝-












'JAVA Study' 카테고리의 다른 글

PATTERN 모음집  (0) 2019.01.31
배열의 데이터를 조건에 맞게 분류 하기  (0) 2019.01.31
try catch fianlly  (0) 2019.01.30
배열 기초  (0) 2019.01.14
ArrayList 사용법과 조회 방법에 관하여  (0) 2019.01.14