2013-07-01 5 views
5

자바에서 두 배열 (반드시 같은 크기는 아님)을 합친 결과를 반환하는 함수를 작성하고 있습니다.배열을 Java로 합치는 방법

여기 내 시도입니다 :

public static <T> T[] sumArrays(T[] lhs, T[] rhs) 
    { 
     T[] out = new T[Math.max(lhs.length, rhs.length)]; 

     for (int i = 0; i < Math.max(lhs.length, rhs.length); ++i){    
      if (i < Math.min(lhs.length, rhs.length)){ 
       out[i] = lhs[i] + rhs[i];     
      } else if (i < lhs.length){ 
       out[i] = lhs[i]; 
      } else /* if (i < rhs.length)*/{ 
       out[i] = rhs[i]; 
      }    
     } 
     return out;   
    } 

하지만 컴파일 오류에도 불구하고 여러 관측이있다.

  1. 극단적으로 거대한 Java 라이브러리에서이 기능이 작동하지 않는 이유는 무엇입니까?

  2. C++에서 템플릿을 사용하는 것처럼 제네릭을 사용하도록 유도되었습니다.

  3. 입력 데이터를 자세히 복사하는 것에 대해 걱정이됩니다. lhs와``rhs. 아무도 이것에 대해 나를 안심시킬 수 있습니까? C++에서는 상수 참조를 전달할 수 있습니다. 그리고 나는 확실히 알 것이다.

  4. T[] 인스턴스화는 제네릭 유형이 잘못되었습니다. 내가 뭘 놓치고 있니?

  5. 컴파일러가 내 Math.max(lhs.length, rhs.length)을 반복해서 최적화합니까?

  6. 컴파일러는 lhs[i] + rhs[i]을 좋아하지 않습니다. 아마도 T의 유형을 모르기 때문에 C++에서는 유형을 알기 전까지 템플릿을 컴파일하지 않으므로이 작업을 수행 할 수 있습니다.

6) 반환 할 때 깊은 사본을 가져 오겠습니까? 다시 C++ 컴파일러는 추가 복사본을 가져 오지 않습니다.

은 아마도 내가 익숙해 너무 늙었 자바 ;-)

+0

광고 3) http://javadude.com/articles/passbyvalue.htm –

+0

길이가 다른 두 배열의 내용을 추가하는 것은 일반적으로 공통된 사항이 아닙니다. 나는 결코 그것을 해 본 적이 없다. 그런 다음 두 배열을 나누는 방법, 두 배열을 빼는 방법, 한 배열에서 한 배열을 다른 배열로 옮기는 방법 등이 있습니다. Java는 필요할 때 도구를 제공합니다. –

+1

'T'는 런타임에 알 수 없습니다. 그래서 당신은'new T [] '를 할 수 없다. – blank

답변

8

0)되지 않는 이유는 매우 거대한 자바 라이브러리에서이 기능을?

의견을 말하기, 여기에서 주제를 물어보십시오.

2) 나는 입력 데이터의 깊은 사본을 얻는 것에 대해 걱정하고 있습니다. lhs 및 rhs. 아무도 이것에 대해 나를 안심시킬 수 있습니까? C++에서는 상수 참조를 전달할 수 있습니다. 그리고 나는 확실히 알 것이다.

6) 돌아올 때 깊은 사본을 가지고 가려고합니까? 다시 C++ 컴파일러는 추가 복사본을 가져 오지 않습니다.

자바에서는 자동으로 깊은 복사가 수행되지 않습니다. 또한 딥 복사는 일반적으로 잘 정의되지 않은 문제입니다.

3) T[]의 인스턴스화는 제네릭 형식에서 잘못된 것으로 보입니다. 내가 뭘 놓치고 있니?

제네릭 형식의 배열을 인스턴스화 할 수 있다는 점 외에도 제네릭 형식은 참조 형식 만 포괄합니다. 여기에서는 기본 유형에만 관심이 많으므로 아무 쓸모가 없습니다.

4) 컴파일러가 내 Math.max(lhs.length, rhs.length)을 반복하여 최적화 할 예정입니까?

일부 JIT는있을 수 있지만 어떠한 보장도 할 수 없습니다. 지역 변수로 추출하십시오.

5) 컴파일러는 lhs[i] + rhs[i]을 좋아하지 않습니다. 아마도 T 유형을 모르기 때문에 아마도 C++에서는 형식을 알기 전까지는 템플릿을 컴파일하지 않으므로이 작업을 수행 할 수 있습니다.

불행히도, 여기에 많은 어려움이 있습니다. 모든 원시 Java 유형에 대해 알고리즘을 생성 할 수있는 방법은 없습니다.

+0

흠, +1을 사용할 수 없습니다. Java가 다른 언어를 개선하는 방법을 고려할 때 우아함을 빚지고 있기 때문에 비판으로 해석 할 수는 없지만 위의 내용은 모두 C++에서 템플릿을 사용하여 쉽게 완성되었을 것입니다. 나는 T 대신에 double을 사용하는 버전을 만들어야한다고 생각한다. – Bathsheba

+0

@ Bathsheba C++에서는 노예 농구에 농구를 추가하려고하면 어떻게 될까? 작성한대로 코드에서 허용합니다 (컴파일러가 객체를 생성하지 않은 경우) –

+2

C++ 템플릿은 특정 유형의 컴파일 시간에 인스턴스화되므로 Java Generics와는 관계가 없습니다. 예, JG는 엄청난 추력 대 비율을 가진 자바의 절름발이 기능이며 이미 그 효과에 대해 많은 비판을 받았습니다. –

1

5) 컴파일러는 lhs [i] + rhs [i]를 좋아하지 않습니다. 아마도 은 T의 유형을 알지 못하기 때문에 C++에서는이를 수행 할 수 있으므로 은 유형을 알 때까지 템플릿을 컴파일하지 않습니다.

항상 .add (...) 함수를 사용하여 인터페이스를 작성하고 T가이 인터페이스를 확장하도록 할 수 있습니다. 그런 다음 lhs [i] .add (rhs [i])를 쓸 수 있습니다.

관련 문제