fender
21k
2016-11-25 16:31:55 작성 2016-11-25 16:36:21 수정됨
7
3582

방금 경험한 스칼라로 전향하기 잘했다고 느끼게한 코드


사실 복잡한 코드는 아니지만, 방금 작성한 코드를 보다가 문득 이걸 자바로 짰으면 어땠을까 생각해보니 스칼라로 전향하기 잘했다는 기분이 들어서 내용을 공유해봅니다.

스칼라 코드:

def getItems: Seq[ChoiceItem] = {
  def asList(name: String) = attrs(name).toSeq.flatMap(_.split(",")).map(_.trim)
  (asList("labels") zip asList("values")) map ChoiceItem.tupled
}

case class ChoiceItem(label: String, value: String)

동일한 내용의 자바 버전:

    private List<String> asList(String name) {
        String values = attrs(name);

        if (values == null) {
            return Collections.emptyList();
        }

        String[] list = values.split(",");
        List<String> result = new ArrayList<String>();

        for (String value : list) {
            result.add(values.trim());
        }

        return result;
    }

    public List<ChoiceItem> getItems() {
        List<String> labels = asList("labels");
        List<String> values = asList("values");

        assert labels.size() == values.size();

        List<ChoiceItem> items = new LinkedList<ChoiceItem>();

        for (int i = 0; i < labels.size(); i++) {
            items.add(new ChoiceItem(labels.get(i), values.get(i)));
        }

        return items;
    }

...

public class ChoiceItem {

    private String label;

    private String value;

    public ChoiceItem(String label, String value) {
        this.label = label;
        this.value = value;
    }

    public String getLabel() {
        return label;
    }

    public String getValue() {
        return value;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        ChoiceItem that = (ChoiceItem) o;

        if (!label.equals(that.label)) return false;

        return value.equals(that.value);
    }

    @Override
    public int hashCode() {
        int result = label.hashCode();

        result = 31 * result + value.hashCode();

        return result;
    }
}
스칼라도 나름의 지저분한 구석이 있지만 적어도 컬렉션 다루는 것 만큼은 확실히 간결하고 편하다는 생각이 듭니다.
0
  • 댓글 7

  • 칸나
    1k
    2016-11-25 16:34:18 작성 2016-11-25 16:34:39 수정됨

    전 한번 저렇게 유틸성 함수를 많이 제공하는 언어를 접하니까 다시 자바는 못하겠더라구요

    이 언어는 이렇게 간단한데 자바는 뭐이렇게 코드를 많이 써야대! 안해!

  • de
    2016-11-25 17:23:08

    자바8 람다 스트림에 롬복쓰면 엄청 줄어듭니다 ㅎㅎ

  • zepinos
    20k
    2016-11-25 17:24:01

    아쉽게도 절반이 빈의 기본적 내용이군요. 저건 그냥 lombok 으로 5줄 정도로(setter 가 반드시 없어야 한다면 좀 더 길구요) 구현도 가능할 것 같네요. 그리고 JDK 8 로 처리하면 또 줄어들 것 같은데요...


    그냥 전 다른거 쓴다면 코틀린 쪽으로...




  • fender
    21k
    2016-11-25 17:28:42 작성 2016-11-25 17:29:05 수정됨

    사실 자바8은 저도 안해봐서 궁금하기도 해서 살짝 시도는 해봤습니다. 예컨대 'asList'는 널체크 제외하면 아래와 같이 바꿀 수는 있더군요:

    Arrays.stream(attrs(name).split(",")).map(vaue -> values.trim()).collect(Collectors.toList())


    다만 getItems 구문은 스트림에 zip 기능이 기본지원되지 않아서 어떻게 해도 크게 줄진 않을 것 같습니다.


    사실 Lombok을 쓰면 빈 선언은 줄일 수 있고 컬렉션 라이브러리를 쓰면 또 줄일 수는 있겠죠... 그래도 언어 자체의 표현력의 차이라는 것도 의미가 있다고 생각하기에 스칼라의 케이스 클래스나 컬렉션 API등은 확실한 장점이라고 생각합니다.


  • 말년개발
    2k
    2016-11-25 17:29:10

    저도 스칼라 한표~!

  • Jet Li
    102
    2016-11-25 18:40:25 작성 2016-11-25 18:44:44 수정됨

    하스켈 버전 꼽사리 끼어 봅니다.  하핫


    data ChoiceItem = ChoiceItem Text Text
    
    getItems :: [ChoiceItem]
    getItems  = zipWith ChoiceItem (asList "lables") (asList "values")
      where
        asList str =  strip <$> splitOn "," (attrs str)


  • vernum
    972
    2016-12-08 08:39:22

    zip, tuple은  jooq jool.... 어는 정도되지만 스칼라가 좋아보이네요

  • 로그인을 하시면 댓글을 등록할 수 있습니다.