2014-07-04 2 views
3

초급 자바 질문 :java collections는 값 또는 참조를 저장합니까?

Integer i = 6; 
ArrayList<Integer> ar = ArrayList<Integer>(); 
ar.add(i); 

이있을 때 그때 i = 8, ar.get(0) 반환 6 물품.

그러나 나는 내 클래스와 같은 일 트라이 경우 :

class MyC 
{ 
    Integer i; 
} 
MyC myc = new MyC(); 
myc.i = 6; 
ArrayList<MyC> ar = ArrayList<MyC>(); 
ar.add(myc); 

다음 myc.i = 8, ar.get(0) 반환 8를 수행하십시오.

이 문제를 설명해 주시겠습니까?

+3

오토 박싱으로 혼란스러워지고 있습니다. 'i = 8'은 정수 일 때보 다 조금 더 복잡합니다. –

+0

이것은 실제로는 매우 간단하지만 실제로는 매우 복잡한 질문입니다. autoboxing에주의를 가져 오기까지 엄지 손가락. – EpicPandaForce

+0

'ar.get (0)'은 8을 반환하지 않습니다.'ar.get (0) .i'는 8을 반환합니다. –

답변

1

이다. 두 번째 예에서는 myc과 첫 번째 요소 인 ar의 참조가 하나만 있습니다.

의견에서 Sotirios가 지적한 것처럼 i이 원시적 인 경우 동일한 결과를 얻게됩니다. 그러나 때문에 약간 다른 이유 :

여기
int i = 6; 
ArrayList<Integer> ar = ArrayList<Integer>(); 
ar.add(i); 
i = 8; // changes not a ref, but value on stack 
System.out.println(ar.get(0)); // prints out 6 

당신이하지 두 개의 참조를 가지고 있지만, 하나는 (ar 내부 Integer를 오토 박싱합니다).

+2

당신의 대답이 독자가 오해의 소지가있는 것 같아서'i'가'int'라면 결과가 달라질 것이라고 생각하게됩니다. –

+0

그 결과는 똑같을 것입니다. 업데이트 된 답변. –

0

Java의 모든 변수는 힙에있는 오브젝트를 참조하는 참조입니다.

래퍼 클래스 (예 : Integer)는 특별한 경우입니다. 이들은 플라이급 패턴을 구현하며 변경할 수 없습니다. iInteger 유형,하지 int이기 때문에 지금이 참조가 있으므로 i = 8는, i = new Integer(8)에 컴파일러에 의해 설정되어 있기 때문에

+1

나는 그것이 오토 박싱의 문제라고 생각하지 않는다. 첫 번째 예제에서 삽입 후 i에 대한 포인터가 변경되고 두 번째 예제에서는 myc 객체 자체가 변경됩니다. –

1

Integer은 기본 유형 int 인 Object-wrapper입니다.

List<Integer> list = new ArrayList<Integer>()과 같이 Collection에 저장하려면 저장된 요소 유형이 Object의 서브 클래스 여야합니다. 참고로 모든 오브젝트가 저장된 따라서, 이들은 참고로 저장된

List<Integer> list = new ArrayList<Integer>(); 
list.add(5); 
int number = list.get(0); 
System.out.println("" + number); 

이유 경우 것을 주목하는 것이 중요하다 (모든 방법들이 값에 의해 참조 수신 Parameter passing in Java 참조) 이유는 5 자동 권투 때문에 숫자를 추가하는 데 사용할 수 있습니다. 목록에서 숫자를 가져올 때도 암묵적으로 .intValue()를 호출하고 래퍼의 값을 프리미티브 int로 반환합니다. 그런 다음 println() 함수에서 숫자는 암시 적으로 Integer에 boxed되고 toString()이 호출됩니다.

0

다른 개체에 가리키는 i은 (원본) 개체를 변경하지 않습니다. 이것은 프리미티브에만 국한된 것은 아닙니다. 당신이 List<List<Object>> 또는 List<List<String>>이 말 : 당신이 지금 wrapper을 반복하면

 List<List<String>> wrapper = new ArrayList<List<String>>(); 

     List<String> l1 = new ArrayList<String>(); 

     wrapper.add(l1); 

     l1 = new ArrayList<String>(); 
     l1.add("hello"); 
     for(List<String> list : wrapper) 
     { 
      for(String string : list) 
      { 
       System.out.println(string); 
      } 
     } 

당신이 그것을 한 빈 목록이 포함되어 찾을 수 있습니다. 이는 첫 번째 예와 동일합니다.wrapper 지금 하나 개의 값 (1 개) 목록이 포함되어 있습니다이 경우

 List<List<String>> wrapper = new ArrayList<List<String>>(); 

     List<String> l1 = new ArrayList<String>(); 

     wrapper.add(l1); 

     l1.add("hello"); 
     for(List<String> list : wrapper) 
     { 
      for(String string : list) 
      { 
       System.out.println(string); 
      } 
     } 

: 같은 두 번째 예를 보인다.

+0

원래 ArrayList를 래퍼에 저장하고 있기 때문에 변수의 참조 만 수정하면됩니다. 하지만 실제로 래퍼에 저장된 원래 ArrayList가 아닙니다. – EpicPandaForce

2

문제는 자동 응답과 관련이 없다는 답변도 있습니다.

첫 번째 예에서는 Integer를 만들고 ArrayList에 넣습니다. 그런 다음 i이 다른 Integer를 가리 키도록 포인터를 정수로 변경합니다. 이 값은 ArrayList의 정수에는 영향을주지 않습니다.

두 번째 예제에서는 객체를 만들고 ArrayList에 넣습니다. 다음이 개체의 상태를 myc.i = 8 변경합니다. 이렇게하면 ArrayList의 개체가 변경됩니다.

2

모든 변수는 기본 유형을 제외하고 값이 아닌 참조를 저장합니다.

첫번째 예

Integer i = 6; 

(IT I1를 불러올 수) 및 i

ArrayList<Integer> ar = ArrayList<Integer>(); 
ar.add(i);` 

에 대한 참조를 저장 ArrayList을 생성하고 저장할 새로운 Integer 객체를 만들기 I1 in

i = 8; 

새로운 (다른) Integer 객체를 생성는 i = I2ar.get(0) = I1

을하고 그래서 지금

i에 대한 참조를 저장합니다 (I2를 호출 할 수 있습니다)

제 2 예의

MyC myc = new MyC(); 

만들기 새로운 MyCmyc

myc.i = 6; 

에에에에 대한 참조를 저장 (호출 할 수 있습니다 I1) 새로운 Integer 객체를 생성하고 여기에 대한 참조를 저장 (의이 C를 부르 자) C.

ArrayList<MyC> ar = ArrayList<MyC>(); 
ar.add(myc); 

iArrayList을 만들고 그것에 에 C를 참조를 저장한다.

myc.i = 8 

Integer 새로운 오브젝트를 생성하고이 C에 대한 참조를 저장 (IT I2를 불러올 수). i

이제 myc = C = I2myc.i, ar.get(0)= C 때문에 ar.get(0).i = I2.

아무 것도 참조하지 않습니다. I1 가비지 수집됩니다.

관련 문제