1. 개요

이 사용방법(예제)에서는 Java 메서드에서 여러 값을 반환하는 다양한 방법을 배웁니다.

먼저 배열과 컬렉션을 반환합니다. 그런 다음 복잡한 데이터에 컨테이너 클래스를 사용하는 방법을 보여주고 일반 튜플 클래스를 만드는 방법을 배웁니다.

마지막으로 타사 라이브러리를 사용하여 여러 값을 반환하는 방법에 대한 예를 살펴 보겠습니다.

2. 어레이 사용

배열은 원시 데이터 유형과 참조 데이터 유형을 모두 반환하는 데 사용할 수 있습니다 .

예를 들어 다음 getCoordinates 메서드는 두 개의 double 값으로 구성된 배열을 반환 합니다.

double[] getCoordinatesDoubleArray() {
  
    double[] coordinates = new double[2];

    coordinates[0] = 10;
    coordinates[1] = 12.5;
  
    return coordinates;
}

다른 참조 유형의 배열을 반환하려면 공통 부모 유형을 배열 유형으로 사용할 수 있습니다 .

Number[] getCoordinatesNumberArray() {
  
    Number[] coordinates = new Number[2];

    coordinates[0] = 10;   // Integer
    coordinates[1] = 12.5; // Double
  
    return coordinates;
}

여기 에서는 IntegerDouble 요소 사이의 공통 클래스이기 때문에 Number 유형 좌표 배열을 정의했습니다 .

3. 컬렉션 사용

일반적으로 자바 컬렉션 , 우리는 일반적인 유형의 여러 값을 반환 할 수 있습니다 .

컬렉션 프레임 워크에는 광범위한 클래스와 인터페이스가 있습니다. 그러나이 섹션에서는 ListMap 인터페이스에 대한 논의를 제한합니다 .

3.1. List에서 유사한 유형의 값 반환

먼저 List <Number> 를 사용하여 이전 어레이 예제를 다시 작성해 보겠습니다 .

List<Number> getCoordinatesList() {
  
    List<Number> coordinates = new ArrayList<>();
  
    coordinates.add(10);  // Integer
    coordinates.add(12.5);  // Double
  
    return coordinates;
}

마찬가지로 번호 []List <번호> 수집은 모두 동일한 일반적인 유형의 혼합형 요소의 시퀀스를 유지한다.

3.2. 맵에서 명명 된 값 반환

컬렉션의 각 항목에 이름을 지정하려면 대신 Map을 사용할 수 있습니다.

Map<String, Number> getCoordinatesMap() {
  
    Map<String, Number> coordinates = new HashMap<>();
  
    coordinates.put("longitude", 10);
    coordinates.put("latitude", 12.5);
  
    return coordinates;
}

getCoordinatesMap 메서드 사용자는 Map # get 메서드  와 함께 " 경도" 또는 " 위도" 키를 사용 하여 해당 값을 검색 할 수 있습니다.

4. 컨테이너 클래스 사용

배열 및 컬렉션과 달리 컨테이너 클래스 (POJO)는 데이터 유형이 다른 여러 필드를 래핑 할 수 있습니다 .

예를 들어, 다음 Coordinates 클래스에는 doubleString 두 가지 데이터 유형이 있습니다 .

public class Coordinates {
  
    private double longitude;
    private double latitude;
    private String placeName;
  
    public Coordinates(double longitude, double latitude, String placeName) {
  
        this.longitude = longitude;
        this.latitude = latitude;
        this.placeName = placeName;
    }
  
    // getters and setters
}

Coordinates 와 같은 컨테이너 클래스를 사용하면 의미있는 이름으로 복잡한 데이터 유형을 모델링 할 수 있습니다 .

다음 단계는 Coordinates 인스턴스를 인스턴스화하고 반환하는 것입니다 .

Coordinates getCoordinates() {
  
    double longitude = 10;
    double latitude = 12.5;
    String placeName = "home";
  
    return new Coordinates(longitude, latitude, placeName);
}

우리는주의해야한다 우리가 같은 데이터 클래스 확인하는 것이 좋습니다 좌표 불변 . 그렇게함으로써 간단하고 스레드로부터 안전하며 공유 가능한 객체를 생성합니다.

5. 튜플 사용

컨테이너와 마찬가지로 튜플은 다양한 유형의 필드를 저장합니다. 그러나 응용 프로그램별로 다르지 않습니다 .

그것들은 우리가 처리하기를 원하는 유형을 설명하기 위해 사용할 때 전문화되지만 특정 수의 값을 포함하는 범용 컨테이너입니다. 즉, 사용자 지정 코드를 작성할 필요가 없으며 라이브러리를 사용하거나 공통 단일 구현을 만들 수 있습니다.

튜플은 필드 수에 제한이 없으며 종종 튜플 n 이라고 합니다. 여기서 n은 필드 수입니다. 예를 들어 Tuple2는 2 필드 튜플이고 Tuple3은 3 필드 튜플입니다.

튜플의 중요성을 보여주기 위해 다음 예제를 살펴 보겠습니다. Coordinates 포인트와 List <Coordinates> 내부의 다른 모든 포인트 사이의 거리를 찾고 싶다고 가정합니다 . 그런 다음 가장 먼 좌표 객체를 거리와 함께 반환해야합니다.

먼저 일반적인 두 필드 튜플을 생성 해 보겠습니다.

public class Tuple2<K, V> {

    private K first;
    private V second;
  
    public Tuple2(K first, V second){
        this.first = first;
        this.second = second;
    }

    // getters and setters
}

다음으로 로직을 구현하고 Tuple2 <Coordinates, Double> 인스턴스를 사용하여 결과를 래핑 하겠습니다 .

Tuple2<Coordinates, Double> getMostDistantPoint(List<Coordinates> coordinatesList, 
                                                       Coordinates target) {

    return coordinatesList.stream()
      .map(coor -> new Tuple2<>(coor, coor.calculateDistance(target)))
      .max((d1, d2) -> Double.compare(d1.getSecond(), d2.getSecond())) // compare distances
      .get();
}

사용 Tuple2 <좌표, 더블> 이전 예제에서이 특정 방법으로 한 번 사용하기 위해 별도의 컨테이너 클래스를 만드는에서 우리를 구원했다 .

컨테이너와 마찬가지로 튜플은 불변이어야합니다 . 또한 범용 특성으로 인해 공개 API의 일부가 아닌 내부적으로 튜플을 사용해야합니다 .

6. 타사 라이브러리

일부 타사 라이브러리는 변경 불가능한 또는 삼중 유형을 구현했습니다 . Apache Commons Langjavatuples 가 대표적인 예입니다. 애플리케이션에서 이러한 라이브러리를 의존성으로 갖게되면 자체적으로 라이브러리를 생성하는 대신 라이브러리에서 제공 하는 Pair 또는 Triple 유형을 직접 사용할 수 있습니다 .

Apache Commons Lang을 사용하여 Pair 또는 Triple 객체 를 반환하는 예를 살펴 보겠습니다 .

더 나아 가기 전에 pom.xmlcommons-lang3 의존성을 추가해 보겠습니다 .

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.11</version>
</dependency>

6.1.  Apache Commons Lang의 ImmutablePair

Apache Commons Lang ImmutablePair 유형은 정확히 우리가 원하는 것입니다. 사용이 간단한 불변 유형입니다.

여기에는 leftright 필드가 있습니다 . getMostDistantPoint 메소드가 ImmutablePair 유형 의 객체를 반환 하도록 만드는 방법을 살펴 보겠습니다 .

ImmutablePair<Coordinates, Double> getMostDistantPoint(
  List<Coordinates> coordinatesList, Coordinates target) {
    return coordinatesList.stream()
      .map(coordinates -> ImmutablePair.of(coordinates, coordinates.calculateDistance(target)))
      .max(Comparator.comparingDouble(Pair::getRight))
      .get();
}

6.2.  Apache Commons Lang의 ImmutableTriple

ImmutableTriple는 받는 매우 유사하다 ImmutablePair . 유일한 차이점은 이름에서 알 수 있듯이 ImmutableTriple 에는 left , middleright의 세 필드가 포함되어 있다는 것 입니다.

이제 ImmutableTriple 유형 을 사용하는 방법을 보여주기 위해 좌표 계산에 새 메서드를 추가해 보겠습니다 .

List <Coordinates>의 모든 지점 을 살펴보고 주어진 목표 지점 까지최소 , 평균최대 거리를 알아낼 것 입니다.

ImmutableTriple 클래스를 사용하여 단일 메서드로 세 값을 반환하는 방법을 살펴 보겠습니다 .

ImmutableTriple<Double, Double, Double> getMinAvgMaxTriple(
  List<Coordinates> coordinatesList, Coordinates target) {
    List<Double> distanceList = coordinatesList.stream()
      .map(coordinates -> coordinates.calculateDistance(target))
      .collect(Collectors.toList());
    Double minDistance = distanceList.stream().mapToDouble(Double::doubleValue).min().getAsDouble();
    Double avgDistance = distanceList.stream().mapToDouble(Double::doubleValue).average().orElse(0.0D);
    Double maxDistance = distanceList.stream().mapToDouble(Double::doubleValue).max().getAsDouble();

    return ImmutableTriple.of(minDistance, avgDistance, maxDistance);
}

7. 결론

이 기사에서는 배열, 컬렉션, 컨테이너 및 튜플을 사용하여 메서드에서 여러 값을 반환하는 방법을 배웠습니다. 단일 데이터 유형을 래핑하기 때문에 간단한 경우에 배열과 컬렉션을 사용할 수 있습니다.

반면에 컨테이너와 튜플은 더 나은 가독성을 제공하는 컨테이너와 함께 복잡한 유형을 만드는 데 유용합니다.

또한 일부 타사 라이브러리가 쌍 및 삼중 유형을 구현하고 Apache Commons Lang 라이브러리의 몇 가지 예를 확인했습니다.

평소처럼이 문서의 소스 코드는 GitHub에서 사용할 수 있습니다 .