IT TIP

java.util.HashSet에 get (Object o) 메소드가없는 이유는 무엇입니까?

itqueen 2020. 12. 25. 10:40
반응형

java.util.HashSet에 get (Object o) 메소드가없는 이유는 무엇입니까?


Set인덱스 값을 기반으로의 개체를 가져 오는 것에 대한 다른 질문을 보았 으며 이것이 불가능한 이유를 이해합니다. 그러나 나는 왜 객체에 의한 가져 오기가 허용되지 않는지에 대한 좋은 설명을 찾을 수 없었으므로 물어볼 것이라고 생각했습니다.

HashSeta로 백업 HashMap이 매우 간단해야부터 그래서 점점 객체. 현재로서는의 각 항목을 반복하고 HashSet불필요 해 보이는 동등성을 테스트해야 할 것으로 보입니다.

a를 사용할 수는 Map있지만 키 : 값 쌍이 필요하지 않습니다 Set.

예를 들어 다음과 같이 말합니다 Foo.java.

package example;

import java.io.Serializable;

public class Foo implements Serializable {

    String _id;
    String _description;

    public Foo(String id){
        this._id = id
    }

    public void setDescription(String description){
        this._description = description;
    }

    public String getDescription(){
        return this._description;
    }

    public boolean equals(Object obj) {
        //equals code, checks if id's are equal
    }

    public int hashCode() {
        //hash code calculation
    }

}

Example.java:

package example;

import java.util.HashSet;

public class Example {

    public static void main(String[] args){
        HashSet<Foo> set = new HashSet<Foo>();

        Foo foo1 = new Foo("1");
        foo1.setDescription("Number 1");

        set.add(foo1);
        set.add(new Foo("2"));

        //I want to get the object stored in the Set, so I construct a object that is 'equal' to the one I want.
        Foo theFoo = set.get(new Foo("1")); //Is there a reason this is not allowed?
        System.out.println(theFoo.getDescription); //Should print Number 1
    }

}

equals 방법이 "논리적"동등성보다는 "절대적인"동등성을 테스트하기위한 것이기 때문입니까 (어떤 경우에 contains(Object o)충분할까요)?


A Set복제물 Collection로 취급하는 객체 a.equals(b) == true이므로 이미 가지고있는 동일한 객체를 얻으려고 시도하는 것은 의미가 없습니다.

get(Object)컬렉션에서 시도하는 경우 a Map가 더 적절할 수 있습니다.

당신이 써야 할 것은

Map<String, String> map = new LinkedHashMap<>();

map.put("1", "Number 1");
map.put("2", null);
String description = set.get("1");

객체가 세트 (같음 기준)에 없으면 추가하고, 세트 (같음 기준)에 있으면 해당 객체의 세트 인스턴스를 제공합니다.

드물게 필요한 경우 Map.

Map<Bar, Bar> map = // LinkedHashMap or ConcurrentHashMap

Bar bar1 = new Bar(1);
map.put(bar1, bar1);

Bar bar1a = map.get(new Bar(1));

자바 맵 / 컬렉션 치트 시트

키 / 값 쌍 또는 값만 포함됩니까?

1) If it contains pairs, the choice is a map. Is order important?

. 1-1) If yes, follow insertion order or sort by keys?

. . 1-1-1) If ordered, LinkedHashMap

. . 1-1-2) If sorted, TreeMap

. 1-2) If order is not important, HashMap

2) If it stores only values, the choice is a collection. Will it contain duplicates?

. 2-1) If yes, ArrayList

. 2-2) If it will not contain duplicates, is primary task searching for elements (contains/remove)?

. . 2-2-1) If no, ArrayList

. . 2-2-2) If yes, is order important?

. . . 2-2-2-1) If order is not important, HashSet

. . . 2-2-2-2) If yes, follow insertion order or sort by values?

. . . . 2-2-2-2-1) if ordered, LinkedHashSet

. . . . 2-2-2-2-2) if sorted, TreeSet


Your last sentence is the answer.

get(Object o) would run through the HashSet looking for another object being equal to o (using equals(o) method). So it is indeed the same as contains(o), only not returning the same result.


If you want to know that new Foo("1"); object is already present in the set then you need to use contains method as:

boolean present =  set.contains(new Foo("1"));

The get kind of method i.e. set.get(new Foo("1")); is not supported because it doesn't make sense. You are already having the object i.e. new Foo("1") then what extra information you would be looking through get method.


HashSet is a little bit simplier than HashMap. If you don't need the features of HashMap, why use it? If the method like getObject(ObjectType o) was implemented by Java we dont need to iterate over the set after calling contain() methode...


The reason why there is no get is simple:

If you need to get the object X from the set is because you need something from X and you dont have the object.

If you do not have the object then you need some means (key) to locate it. ..its name, a number what ever. Thats what maps are for right.

map.get( "key" ) -> X!

Sets do not have keys, you need yo traverse them to get the objects.

So, why not add a handy get( X ) -> X

That makes no sense right, because you have X already, purist will say.

But now look at it as non purist, and see if you really want this:

Say I make object Y, wich matches the equals of X, so that set.get(Y)->X. Volia, then I can access the data of X that I didn have. Say for example X has a method called get flag() and I want the result of that.

Now look at this code.

Y

X = map.get( Y );

So Y.equals( x ) true!

but..

Y.flag() == X.flag() = false. ( Were not they equals ?)

So, you see, if set allowed you to get the objects like that It surely is to break the basic semantic of the equals. Later you are going to live with little clones of X all claming that they are the same when they are not.

You need a map, to store stuff and use a key to retrieve it.


if you only want know what are in the Hashset, you can use .toString(); method to display all Hashset Contents separated by comma.


As everyone mentioned before, there is no such method and for good reasons. That being said, if you wish to get a certain object from a HashSet in java 8 using a one-liner (almost), simply use streams. In your case, it would be something like:

Foo existing = set.stream().filter(o -> o.equals(new Foo("1"))).collect(Collectors.toList()).iterator().next();

Note that an exception will be thrown if the element doesn't exist so it is technically not a one-liner, though if the filter is properly implemented it should be faster than a traditional iteration over the collection elements.


A common use case of a get method on Set might be to implement an intern set. If that's what you're trying to achieve, consider using the Interner interface and Interners factory from Google Guava.

ReferenceURL : https://stackoverflow.com/questions/13863506/why-doesnt-java-util-hashset-have-a-getobject-o-method

반응형