import java.util.Arrays;

import java.util.List;

import java.util.Map;

import java.util.stream.Collectors;


import org.apache.commons.lang3.StringUtils;


import org.junit.Test;

import org.springframework.util.Assert;


public class Java8Test {

class Member {

int id;

String name;

public Member(int id, String name) {

this.id = id;

this.name = name;

}

}

@Test

public void test1() {

Member member1 = new Member(1, "samuel");

Member member2 = new Member(2, "keans");

Member member3 = new Member(3, "xy");

List<Member> members =  Arrays.asList(member1, member2, member3);

Map<Boolean, List<Member>> results = members.stream().collect(Collectors.partitioningBy(m -> StringUtils.startsWith(m.name, "x")));

results.forEach((k, v) -> System.out.println("key:" + k + ", value:" + v.stream().map(member -> member.name).collect(Collectors.joining(", "))));

Assert.isTrue(results.get(true).get(0) == member3);

Assert.isTrue(results.get(false).get(0) == member1);

Assert.isTrue(results.get(false).get(1) == member2);

}

}




결과는 다음과 같다.


key:false, value:samuel, keans

key:true, value:xy




단순히  Collectors.partitionBy 대신 Collectors.groupingBy로 사용할 수도 있다. 


import java.util.Arrays;

import java.util.List;

import java.util.Map;

import java.util.stream.Collectors;


import org.apache.commons.lang3.StringUtils;


import org.junit.Test;

import org.springframework.util.Assert;


public class Java8Test {

class Member {

int id;

String name;

public Member(int id, String name) {

this.id = id;

this.name = name;

}

}

@Test

public void test1() {

Member member1 = new Member(1, "samuel");

Member member2 = new Member(2, "keans");

Member member3 = new Member(3, "xy");

List<Member> members =  Arrays.asList(member1, member2, member3);

Map<Boolean, List<Member>> results = members.stream().collect(Collectors.groupingBy(m -> StringUtils.startsWith(m.name, "x")));

results.forEach((k, v) -> System.out.println("key:" + k + ", value:" + v.stream().map(member -> member.name).collect(Collectors.joining(", "))));

Assert.isTrue(results.get(true).get(0) == member3);

Assert.isTrue(results.get(false).get(0) == member1);

Assert.isTrue(results.get(false).get(1) == member2);

}

}




groupingBy메소드에서는 Aggregation 기능도 제공한다.




import java.util.Arrays;

import java.util.List;

import java.util.Map;

import java.util.function.Function;

import java.util.stream.Collectors;


import org.junit.Test;


public class Java8Test {

class Member {

int id;

String name;

public Member(int id, String name) {

this.id = id;

this.name = name;

}

public String toString() {

return id + ", " + name;

}

}

@Test

public void test1() {

Member member1 = new Member(1, "samuel");

Member member2 = new Member(2, "keans");

Member member3 = new Member(3, "xy");

Member member4 = new Member(4, "keans"); // same name, but not same person

List<Member> members =  Arrays.asList(member1, member2, member3, member4);

Map<Member, Long> results = members.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

results.forEach((k, v) -> System.out.println("key:" + k + ", value:" + v));

System.out.println("");

Map<String, Long> otherResults = members.stream().collect(Collectors.groupingBy(m-> m.name, Collectors.counting()));

otherResults.forEach((k, v) -> System.out.println("key:" + k + ", value:" + v));


}

}


결과는 다음과 같다.


key:2, keans, value:1

key:4, keans, value:1

key:1, samuel, value:1

key:3, xy, value:1


key:xy, value:1

key:samuel, value:1

key:keans, value:2






difference 예제이다. map의 요소 중 특정 key를 제외하고 싶을 때 사용할 수 있는 예제이다.

먼저 groupingBy 또는 parittioningBy를 사용하지 않는 예제이다. 



Map<Integer, Object> maps = Maps.newHashMap();

maps.put(1, "samuel");

maps.put(2, "jackson");

maps.put(3, "ice");

maps.put(4, "xxx");

List<Integer> excludeList = Arrays.asList(4);

List<Integer> keys = maps.entrySet().stream().map(k -> k.getKey()).collect(Collectors.toList());


Map<Integer, Object> map = (Map<Integer, Object>) CollectionUtils.subtract(keys, excludeList).stream().collect(Collectors.toMap(p->p, p->maps.get(p)));

System.out.println(map);



결과는 다음과 같다.


{1=samuel, 2=jackson, 3=ice}




CollectionUtils.subtract 대신 Guava의 Collection2.filter를 사용할 수 있다.
Map<Integer, Object> maps = Maps.newHashMap();
maps.put(1, "samuel");
maps.put(2, "jackson");
maps.put(3, "ice");
maps.put(4, "xxx");
List<Integer> excludeList = Arrays.asList(4);
List<Integer> keys = maps.entrySet().stream().map(k -> k.getKey()).collect(Collectors.toList());
Map<Integer, Object> map = Collections2.filter(keys, Predicates.not(Predicates.in(excludeList)))
.stream().collect(Collectors.toMap(p->p, p->maps.get(p)));
System.out.println(map);




partitioningBy를 사용하면 다르게 구현할 수도 있다. 

Map<Integer, Object> maps = Maps.newHashMap();

maps.put(1, "samuel");

maps.put(2, "jackson");

maps.put(3, "ice");

maps.put(4, "xxx");

List<Integer> excludeList = Arrays.asList(4);

Map<Boolean, Map<Object, Object>> map = maps.entrySet().stream().collect(

Collectors.partitioningBy(p -> !excludeList.contains(p.getKey()), Collectors.toMap(p -> p.getKey(), p -> p.getValue()))

);

System.out.println(map);

System.out.println(map.get(true));


결과는 다음과 같다. 



{false={4=xxx}, true={1=samuel, 2=jackson, 3=ice}}

{1=samuel, 2=jackson, 3=ice}


Posted by 김용환 '김용환'

댓글을 달아 주세요