JAVA8 - Lambda의 List 정렬

5591 단어 JAVA8

먼저 실체 클래스를 정의합니다

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Human {

    private String name;
    private int age;
    
}

아래의 조작은 모두 이 종류에 기초하여 조작을 진행한다.이 안에는 Lombok 라이브러리를 사용했는데 주석의 방식으로 기본적인 get과 set 등의 방법을 실현하여 코드를 더욱 우아하게 보였다.

JAVA8 이전 List 정렬 작업


Java8 이전에는 컬렉션 정렬에 대해 하나의 익명 내부 클래스만 만들 수 있었습니다.
new Comparator() {
    @Override
    public int compare(Human h1, Human h2) {
        return h1.getName().compareTo(h2.getName());
    }
}

다음은 간단한 Humans 정렬(이름별 정렬)
@Test
public void testSortByName_with_plain_java() throws Exception {

   ArrayList humans = Lists.newArrayList(
           new Human("tomy", 22),
           new Human("li", 25)
   );

   Collections.sort(humans, new Comparator() {
         
       public int compare(Human h1, Human h2) {
           return h1.getName().compareTo(h2.getName());
       }
   });

   Assert.assertThat(humans.get(0), equalTo(new Human("li", 25)));
}

Lambda의 List 정렬 사용


JAVA8 함수 방식의 비교기 사용
(Human h1, Human h2) -> h1.getName().compareTo(h2.getName())

다음은 JAVA8 함수식을 사용하여 비교한 예이다
@Test
public void testSortByName_with_lambda() throws Exception {

   ArrayList humans = Lists.newArrayList(
           new Human("tomy", 22),
           new Human("li", 25)
   );
   humans.sort((Human h1, Human h2) -> h1.getName().compareTo(h2.getName()));

   Assert.assertThat("tomy", equalTo(humans.get(1).getName()));

}


유형 정의 정렬 없음


또한 위의 표현식을 단순화할 수 있으며, JAVA 컴파일러는 컨텍스트를 기준으로 정렬 유형을 추정할 수 있습니다.
(h1, h2) -> h1.getName().compareTo(h2.getName())

단순화된 비교기는 다음과 같습니다.
@Test
public void testSortByNameSimplify_with_lambda() throws Exception {

   ArrayList humans = Lists.newArrayList(
           new Human("tomy", 22),
           new Human("li", 25)
   );
   humans.sort((h1, h2) -> h1.getName().compareTo(h2.getName()));

   Assert.assertThat("tomy", equalTo(humans.get(1).getName()));

}   


정적 방법을 사용하여 참조


JAVA8은 또한 Lambda 표현식을 사용하는 정적 유형 참조를 제공할 수 있습니다. Human 클래스에 다음과 같은 정적 비교 방법을 추가합니다.
public static int compareByNameThenAge(Human h1, Human h2) {

   if (h1.getName().equals(h2.getName())) {
       return Integer.compare(h1.getAge(), h2.getAge());
   }
   return h1.getName().compareTo(h2.getName());
}


그리고 Humans에서sort 이 인용 사용하기
@Test
public void testSort_with_givenMethodDefinition() throws Exception {

   ArrayList humans = Lists.newArrayList(
           new Human("tomy", 22),
           new Human("li", 25)
   );
   humans.sort(Human::compareByNameThenAge);
   Assert.assertThat("tomy", is(equalTo(humans.get(1).getName())));
}


개별 Comparator 사용


JAVA8은 이미 많은 편리한 비교기를 제공하여 우리에게 사용하도록 제공했다. 예를 들어Comparator.comparing 방법이므로 Comparator를 사용할 수 있습니다.comparing 메서드는 Human의 name에 따라 비교하는 작업을 수행합니다.
@Test
public void testSort_with_givenInstanceMethod() throws Exception {

   ArrayList humans = Lists.newArrayList(
           new Human("tomy", 22),
           new Human("li", 25)
   );

   Collections.sort(humans, Comparator.comparing(Human::getName));
   Assert.assertThat("tomy", equalTo(humans.get(1).getName()));
}


역순


JDK8에서도 역순 정렬을 지원하는 방법을 제공하여 우리가 더욱 빨리 역순을 진행할 수 있도록 하였다
@Test
public void testSort_with_comparatorReverse() throws Exception {

   ArrayList humans = Lists.newArrayList(
           new Human("tomy", 22),
           new Human("li", 25)
   );

   Comparator comparator = (h1, h2) -> h1.getName().compareTo(h2.getName());
   humans.sort(comparator.reversed());
   Assert.assertThat("tomy", equalTo(humans.get(0).getName()));

}


여러 조건을 사용하여 정렬


Lambda는 보다 복잡한 표현식을 제공하며 age에 따라 정렬하기 전에 name을 정렬할 수도 있습니다.
@Test
public void testSort_with_multipleComparator() throws Exception {

   ArrayList humans = Lists.newArrayList(
           new Human("tomy", 22),
           new Human("li", 25)
   );

   Comparator comparator = (h1, h2) -> {

       if (h1.getName().equals(h2.getName())) {
           return Integer.compare(h1.getAge(), h2.getAge());
       }
       return h1.getName().compareTo(h2.getName());
   };
   humans.sort(comparator.reversed());
   Assert.assertThat("tomy", equalTo(humans.get(0).getName()));

}

여러 조건을 사용하여 정렬 - 조합하는 방법


Comparator는 이러한 조합의 정렬을 더욱 우아하게 구현했습니다. JDK8부터 우리는 체인식 조작을 이용하여 복합 조작을 하여 더욱 복잡한 논리를 구축할 수 있습니다.
@Test
public void testSort_with_multipleComparator_composition() throws Exception {

   ArrayList humans = Lists.newArrayList(
           new Human("tomy", 22),
           new Human("tomy", 25)
   );

   humans.sort(Comparator.comparing(Human::getName).thenComparing(Human::getAge));
   Assert.assertThat(humans.get(0), equalTo(new Human("tomy", 22)));

}

총결산


JDK8은 정말 우리가 배울 만한 버전이다. Lambda 표현식을 제공하고 함수식 프로그래밍 이념을 가져와 JAVA 코드를 더욱 우아하게 한다.

좋은 웹페이지 즐겨찾기