본문 바로가기

JAVA

[JAVA] 키워드 중요도에 따른 노출 순위 표시(Map merge + Map 을 List로 변환 + List sort + java8버전 + 람다식 표현)

특정문장을 형태소분석하고, 많이 노출된 키워드 순으로 10개까지만 노출하는 로직에 사용된 자바 주요 기능 정리입니다. (형태소분석 API를 사용하는 부분은 패스)

 

아래와 같이 문장을 형태소분석한 결과 데이터(Json형태)가 있다고 가정하겠습니다. 

data=[

{id=4.0, text='청년구직활동지원금', head=7.0, label=NP, mod=[], weight=0.0212487}, 

{id=5.0, text=3월부터, head=7.0, label=NP_AJT, mod=[], weight=0.138904}, 
{id=6.0, text=접수, head=7.0, label=NP, mod=[], weight=0.502624}

{id=7.0, text='청년구직활동지원금', head=7.0, label=NP, mod=[], weight=0.0212487}, 

....

]

 

1. Json 데이터를 Map으로 변환

JSON parsing을 위해 Gson 라이브러리를 사용(https://github.com/google/gson)

Map<String, Object> responseBody = gson.fromJson(responseBodyJson, Map.class);

List<Map> sentences = (List<Map>) responseBody.get("sentence");

 

2. java Map의 merge를 통해 키워드 노출 집계

Map<String, Integer> kwrdMap = new HashMap<>();	//중복 허용하지 않음

for( Map<String, Object> sentence : sentences ) {
    String name = (String) sentence.get("text");                
    kwrdMap.merge(name, 1, Integer::sum);	
    //java 1.8부터 지원하는 기능.
    //동일한 키가 없으면 add하고, 이미 키가 있으면 value 값에 +1 을 한다는 의미
}

map의 merge는 중복되는 키가 없으면 add , 있으면 value값 update로 이해하시면 됩니다.

 

 

3. Sort를 위해 Map을 List로 변환

List<NameEntity> kwrdList = new ArrayList<>();
Iterator<String> ito = kwrdMap.keySet().iterator();
while (ito.hasNext()) {
  String keyNm = ito.next();
  NameEntity nameEntity = new NameEntity(keyNm, null, kwrdMap.get(keyNm));
  kwrdList.add(nameEntity);
}

public class NameEntity {
  final String text;
  Integer count;
  public NameEntity (String text, Integer count) {
    this.text = text;
    this.count = count;
  }
}

 

4. List 를 노출순으로 sort (람다식 표현 사용)

//java 1.8 람다식 표현
if(0 < kwrdList.size()){
  kwrdList.sort( (nameEntity1, nameEntity2) -> {
    return nameEntity2.count - nameEntity1.count;
  });
}

람다식 표현에서 (nameEntity1, nameEntity2) 의 변수명은 아무렇게나 사용해도 됩니다. list를 돌면서 현재 객체, 다음객체를 넘겨준다고 이해해주시면 됩니다. 넘겨준 변수를 -> {...함수 로직 처리..} 에서 활용하는 거죠. 그 결과에 따라 sort를 하는 거고요. Collection... compareTo 등 사용하지 않고 쉽게 sort가 되네요. ㅎㅎ

 

 

5. 노출순으로 상위 10개를 표시

kwrdList
.stream()
.limit(10)
.forEach(nameEntity -> {
  System.out.println("[키워드] " + nameEntity.text + " count : " + nameEntity.count);
});

List 객체에서 제공하는 limit와 foreach와 람다식 표현을 사용한까 쉽게 상위 10개를 print할 수 있습니다. ㅎㅎ