du.study기록공간

Java stream sort multiple fields 본문

자바

Java stream sort multiple fields

du.study 2020. 4. 25. 23:24
728x90

stream을 사용하는 도중 자주 사용하지만 자꾸 까먹어 다시 찾아보는 기능을 기록하려합니다.

 

 

우리는 객체를 사용하면서 정렬을 하거나, 정렬을 하고 출력을 하는등에 대한 기능을 사용할 때가 많습니다.

이 기능은 스트림을 사용하면 간단하게 사용할 수 있습니다. 다음은 예제 코드입니다.

 

// Integer List를 reverseOrder한 결과

public static void main(String[] args) {
  List<Integer> list = new ArrayList<>();
  list.add(1);
  list.add(2);
  list.add(45);
  list.add(6);
  list.add(3);
  list.add(7);
  list.add(11);
  list.add(13);
  list.add(1);

  list.stream().sorted(Comparator.reverseOrder()).forEach(s -> System.out.println(s));
}


// 결과 값

45
13
11
7
6
3
2
1
1

 

하지만 보통 우리는 list에 직접 만든 도메인을 추가하고 해당값을 이용하여 sort를 진행합니다.

그럼 아래는 class하나를 선언했다 가정하고 sort하는 코드를 작성하겠습니다.

 

// multi key에 대한 sort.

public static void main(String[] args) {
    List<Product> sss = new ArrayList<>();
    sss.add(new Product(3, 6));
    sss.add(new Product(3, 5));
    sss.add(new Product(5, 7));
    sss.add(new Product(5, 10));


    sss = sss.stream().sorted(Comparator.comparing(Product::getCost, Comparator.reverseOrder()).thenComparing(Product::getCnt)).collect(Collectors.toList());

    for(Product t : sss) {
      System.out.println(t.cost+" "+ t.cnt);
    }
}

class Product{
    int cost;
    int cnt;

    public Product(int cost, int cnt) {
      this.cost = cost;
      this.cnt = cnt;
    }

    public int getCost() {
      return cost;
    }
    public void setCost(int cost) {
      this.cost = cost;
    }
    public int getCnt() {
      return cnt;
    }
    public void setCnt(int cnt) {
      this.cnt = cnt;
    }
}

// 결과 값
5 7
5 10
3 5
3 6

이번 예제의 경우 stream 안에서 forEach를 하지않고 list를 반환하도록 설정했습니다.

해당 결과의 경우, cost의 경우 Comparator.reverseOrder() 를 통하여  cost는 내림차순, cnt는 오름차순을 통해 정렬된 결과를 나타내게 됩니다. (  Comparator.reverseOrder()을 사용하지 않는 경우 기본 오름차순입니다. )

 

또한 마지막 .collect() 부분을 통하여 list를 반환하게 됩니다.

 

 

하지만 여기서.. 비교해야할 field가 많거나, String 내부 단어에 의해 커스텀한 정렬이 필요한경우. 

implements Comparable<Class> 구현을 통하여 해당부분 sort가 가능합니다.

// stream으로 sort받는 부분만 변경
sss = sss.stream().sorted().collect(Collectors.toList());


class Product implements Comparable<Product> {
  // 위와 동일한 getter, setter, constructor

	@Override
	public int compareTo(Product o) {
		if(this.cost > o.cost)
			return -1;
		return 1;
	}
	
}

// 결과 값
5 7
5 10
3 6
3 5

해당 Comparable 구현을 통해서도 sort시 기준을 적용할 수 있게됩니다.

 

 

비교적 Domain에 별다른 implement를 좋아하진 않으나, 복잡하며 반드시 코드상에서 sort가 필요하다면 써야할지도 몰르겠습니다.

728x90

'자바' 카테고리의 다른 글

Java Async - CompletableFuture  (0) 2020.05.25
Java Optional 사용하기  (0) 2020.05.17
Java Map java.util.concurrent.ConcurrentHashMap  (0) 2020.04.06
java.util.Set(1) HashSet  (0) 2020.03.28
Java.util.List Interface(3) Stack  (0) 2020.03.27
Comments