Java의 HashMap에서 key값으로 primitive type은 올 수 없다.

그래서 int가 key값으로 필요하다면 Integer를 대신 사용하게 된다.


그런데 여기에서 짚고 넘어가야 할 점이 하나 있다.

HashMap에서는 key의 hashCode()값을 기준으로 entry를 찾기 때문에

처음 HashMap에 entry를 넣을 때의 key의 hashCode()값과

entry를 불러 올 때의 key의 hashCode()값이 같아야 한다.

그래서 HashMap에 entry를 넣을 때의 Integer의 reference를 유지해야,

나중에 HashMap에서 entry를 불러 올 때 사용할 수 있다라고 생각하기 쉽다.



위의 경우 과연 Integer value는 null일까?

단순히 생각해 봤을때 처음 entry를 넣을 때 Integer 객체를 하나 생성했고

entry를 찾을 때 새로운 Integer 객체를 생성했기 때문에 null값이 나올 것이라고 생각할 수도 있다.

하지만 실제로 해보면 null값이 아니라 30을 값으로 지니는 Integer가 반환된다.


그렇다면 왜 그런 것일까?

이는 Java API의 Integer의 hashCode() 부분을 보면 쉽게 알 수 있다.


hashCode

public int hashCode()
Returns a hash code for this Integer.

Overrides:
hashCode in class Object
Returns:
a hash code value for this object, equal to the primitive int value represented by this Integer object.


즉, Integer의 hashCode()를 호출하면 Integer가 표현하고 있는 primitive int 값을 리턴한다.

Integer를 언제 어디서 얼마나 많이 생성하던지간에, Integer가 표현하는 primitive int값이 같다면 모두 같은 instance를 공유하는것이 된다.

따라서 HashMap에서 Integer를 사용할 때 쓸데없이 많은 생각을 하지 않아도 된다.



위와 같은 HashMap의 사용이 가능한 것도 모두 같은 원리로써 설명이 가능하다.

  

Java transient 키워드에 대해 몰랐던 사실

Posted by epicdev Archive : 2012. 8. 26. 19:10

Java에는 transient라는 키워드가 존재합니다. 예를 들어 아래처럼 클래스의 멤버변수를 선언할 때 붙일 수 있는 키워드입니다.



일반적으로 transient 키워드는 단순히 Java에서 serialization을 할 때, 특정 멤버변수가 serialization이 되는 것을 막는 것이라고 알려져 있습니다.

물론 맞는 말이구요. 그런데 곰곰이 생각해 보면 이게 정말 하나의 프로그래밍 언어에서 키워드로 지정해야할 수준의 중요성을 지니고 있는 것인가? 라는 의문이 들었습니다.


그래서 좀 찾아봤더니 실제로 그런 의견들이 있었습니다.


출처: http://stackoverflow.com/questions/910374/why-does-java-have-transient-variables


Serialization systems other than the native java one can also use this modifier. Hibernate, for instance, will not persist fields marked with either @Transient or the transient modifier. Terracotta as well respects this modifier.

I believe the figurative meaning of the modifier is "this field is for in-memory use only. don't persist or move it outside of this particular VM in any way. Its non-portable". i.e. you can't rely on its value in another VM memory space. Much like volatile means you can't rely on certain memory and thread semantics.


그리고 댓글에는


I think that transient wouldn't be a keyword if it were designed at this time. They'd probably use an annotation


요약을 해보면 이 transient라는 것은 옛날에 Java가 만들어 질 때 만들어 진 키워드입니다.

만약 이러한 기능이 지금에 와서 만들어 졌다면, transient같은 키워드가 아닌 Java 5부터 소개된 Annotation(@)을 활용해서 이러한 것들이 정의되도록 설계를 했을 것입니다. 이것은 volatile같은 키워드에도 똑같이 적용될 수 있습니다.


실제로 이러한 transient나 volatile같은 키워드들은 VM마다 다르게 구현이 되어있기 때문에, JVM이 아닌 다른 VM을 쓸 경우 제대로 동작하지 않을 수도 있다고 합니다.

그래서 결론은, transient를 그냥 단순히 serialization을 방지하는 키워드라고 외우는 것보다는, transient라는 키워드의 본질적인 의미인, 이 멤버 변수는 "메모리 안에서만 사용되어야한다"라는 것을 암시하는 키워드라고 알아두어야 할 것입니다. 그래서 이러한 키워드의 의미를 JVM에서는 serialization이 되지 않도록 구현을 한 것입니다. 다른 VM에서는 어떻게 구현을 하던간에 transient의 본질적인 의미만 어기지 않으면 되는 것입니다.

  

HashSet vs TreeSet

Posted by epicdev Archive : 2012. 8. 23. 20:01

출처: http://stackoverflow.com/questions/1463284/hashset-vs-treeset


HashSet is much faster than TreeSet (constant-time versus log-time for most operations like add, remove and contains) but offers no ordering guarantees like TreeSet.

HashSet:

  • class offers constant time performance for the basic operations (add, remove, contains and size).
  • it does not guarantee that the order of elements will remain constant over time
  • iteration performance depends on the initial capacity and the load factor of the HashSet.
    • It's quite safe to accept default load factor but you may want to specify an initial capacity that's about twice the size to which you expect the set to grow.

TreeSet:

  • guarantees log(n) time cost for the basic operations (add, remove and contains)
  • guarantees that elements of set will be sorted (ascending, natural, or the one specified by you via it's constructor)
  • doesn't offer any tuning parameters for iteration performance
  • offers a few handy methods to deal with the ordered set like first(), last(), headSet(), and tailSet() etc

Important points:

  • Both guarantee duplicate-free collection of elements
  • It is generally faster to add elements to the HashSet and then convert the collection to a TreeSet for a duplicate-free sorted traversal.
  • None of these implementation are synchronized. That is if multiple threads access a set concurrently, and at least one of the threads modifies the set, it must be synchronized externally.
  • LinkedHashSet is in some sense intermediate between HashSet and TreeSet. Implemented as a hash table with a linked list running through it, however it provides insertion-ordered iteration which is not same as sorted traversal guaranteed by TreeSet.

So choice of usage depends entirely on your needs but I feel that even if you need an ordered collection then you should still prefer HashSet to create the Set and then convert it into TreeSet.

  • e.g. Set<String> s = new TreeSet<String>(hashSet);

  
 «이전 1 ··· 4 5 6 7 8 9 10 ··· 55  다음»