반응형

Stream 사용하기 1에 이어서 이번엔 Stream의 sorted를 사용해보겠습니다.

 

배열, 컬렉션에 담긴 데이터를 정렬하는 예제를 보겠습니다.

 

sorted

String배열 정렬하기.

String[] animals = {"rabbit", "fox", "cat", "tiger", "dog"};
Stream.of(animals).sorted().forEach(System.out::println);

정렬된 문자열 스트림

배열데이터에는 stream()을 바로 사용할 수 없으니 Stream.of(T[]) 를통해 스트림을 생성하고 그것을 sorted()를 연결하여 정렬한 데이터를 보여줍니다.

 

Stream.of() 가 싫다면 아래처럼 Arrays.asList()를 통해 배열을 LIST화 시키고 해당 데이터를 정렬합니다.

String[] animals = {"rabbit", "fox", "cat", "tiger", "dog"};
Arrays.asList(animals).stream().sorted().forEach(System.out::println);

동일한 결과를 얻을 수 있습니다.

 

원본 데이터는 영향을 받지 않는다.

여기서 주의할 것은 "원본데이터인 animals라는 배열이 정렬되는게 아니다." 라는 점입니다.

배열데이터가 정렬된게 아닌 새로운 스트림데이터에 정렬된 데이터가 들어있습니다.

String[] animals = {"rabbit", "fox", "cat", "tiger", "dog"};
Arrays.asList(animals).stream().sorted().forEach(System.out::println);

System.out.println();System.out.println();
System.out.println("당연히 원본 배열의 정렬은 그대로이다.");
System.out.println();System.out.println();

Arrays.asList(animals).forEach(System.out::println);

animals 배열은 영향받지 않는다.

 

 

VO 객체 배열을 정렬하기

vo형태로 들어가있는 배열 데이터의 특정값을 기준으로 정렬을 해보겠습니다.

Student Class를 정의합니다.

Student.java

public class Student {
	private String name;
	private int jum;
	
	public Student(String name, int jum) {
		this.name = name;
		this.jum = jum;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getJum() {
		return jum;
	}
	public void setJum(int jum) {
		this.jum = jum;
	}
	
	@Override
	public String toString() {
		return "Student [name=" + name + ", jum=" + jum + "]";
	}
}

 

VO Array Sorted

Student[] sArr = {
		new Student("철수", 79)
		, new Student("영희", 95)
		, new Student("영수", 80)
		, new Student("민희", 85)
		, new Student("유리", 40)
		, new Student("민수", 75)};

Stream<Student> filter_Arr = Stream.of(sArr).sorted(Comparator.comparing((Student s) -> s.getName()));
filter_Arr.forEach(System.out::println);

name을 기준으로 정렬

sArr 배열에 new 생성자를 통해서 학생 6명을 넣고 정렬한 예제입니다.

Comparator 인터페이스의 comparing 메소드를 활용하여 VO객체의 특정 값을 정렬하였습니다.

특정 값은 생성자로 사용한 첫번째 파라미터 name값이 되었습니다.

 

 

여기서 궁금증이 생길수 있습니다. 반대로 정렬은 어떻게 할까요?

reversed() 메소드를 활용하면 됩니다.

Stream<Student> filter_Arr = Stream.of(sArr).sorted(Comparator.comparing((Student s) -> s.getName()).reversed());
filter_Arr.forEach(System.out::println);

반대로 정렬 reversed()

 

LIST<VO> 데이터 정렬하기

List<Student> list = new ArrayList<Student>();
list.add(new Student("철수", 79));
list.add(new Student("영희", 95));
list.add(new Student("영수", 80));
list.add(new Student("민희", 85));
list.add(new Student("유리", 40));
list.add(new Student("민수", 75));

list.stream()
	.sorted(Comparator.comparing((Student s) -> s.getJum()).reversed())
	.forEach(System.out::println);

List<Student> 정렬

네.. 배열안에 있는 VO 데이터나 List안에 있으나 큰 차이는 없습니다.

이번엔 점수가 높은 데이터부터 정렬이 되도록 출력해봤습니다.

 

마지막으로 List<HashMap<Obejct, Object> 형태 정렬하는 방법을 알아보겠습니다.

List<Map>정렬하기

먼저 값이 정수형인 데이터부터 정렬을 해보겠습니다.

List<HashMap<Object, Object>> list = new ArrayList<HashMap<Object, Object>>();
list.add(new HashMap<Object, Object>(){{put("name", "영희");put("jum", 95);}});
list.add(new HashMap<Object, Object>(){{put("name", "영수");put("jum", 80);}});
list.add(new HashMap<Object, Object>(){{put("name", "민수");put("jum", 75);}});
list.add(new HashMap<Object, Object>(){{put("name", "철수");put("jum", 79);}});
list.add(new HashMap<Object, Object>(){{put("name", "민희");put("jum", 85);}});
list.add(new HashMap<Object, Object>(){{put("name", "유리");put("jum", 40);}});
list.add(new HashMap<Object, Object>(){{put("name", "유리");put("jum", 55);}});
list.stream()
	.sorted((s1, s2) -> Integer.compare((int)s1.get("jum"), (int)s2.get("jum")))
	.forEach(System.out::println);

작은 값부터 정렬

Wrapper.class.compare를 통해 정렬을 하였습니다.

첫번째 파라미터가 앞에 있으면 작은값부터 정렬되며, 두번째 파라미터가 앞에 있으면 큰값부터 정렬이 됩니다.

 

파라미터 위치에 따른 정렬 변경

list.stream()
	.sorted((s1, s2) -> Integer.compare((int)s2.get("jum"), (int)s1.get("jum")) )
	.forEach(System.out::println);

큰 값부터 정렬

 

 

다음으로 문자열데이터가 들어간 key값이 "name"인 데이터를 정렬해보겠습니다.

compareTo()

Stream<HashMap<Object, Object>> string_list = list.stream()
			.sorted((s1, s2) -> 
				s1.get("name").toString().compareTo( s2.get("name").toString() )
			);
string_list.forEach(System.out::println);

문자열 정렬

 

반대로 정렬할때는 역시 순서를 바꿔주면 됩니다. 람다식 표현의 s1, s2의 위치를 바꿔주면 됩니다.

Stream<HashMap<Object, Object>> string_list = list.stream()
			.sorted((s1, s2) -> 
				s2.get("name").toString().compareTo( s1.get("name").toString())
			);
string_list.forEach(System.out::println);

문자열 정렬 역순

 

반응형