Search code examples
javacollectionsjava-8

Set to hold key value pairs in java


I am facing a problem where i need to store unique key value pairs in a set. As per my knowledge I can't have key value pairs in set so I am using a map and checking the entryset() values to confirm what I am about to insert doesn't already exist. If i check a pair (a,c) doesnt exist in map but there is (a,b) present, the insert of (a,c) updates the (a,b) entry and I am unable to save both the key value pairs. Please advise how to achieve this.


Solution

  • You can create your custom pair class in case you have no dependency related to pair such as Spring, Guava,... Then you have to override equals and hashcode method to have a set contains elements you wanted:

    @SuppressWarnings("unused")
    public final class Pair<L, R> {
    
        private final L key;
    
        private final R value;
    
        private Pair(final L key, final R value) {
            this.key = key;
            this.value = value;
        }
    
        public static <L, R> Pair<L, R> of(final L key, final R value) {
            return new Pair<>(key, value);
        }
    
        public L getKey() {
            return this.key;
        }
    
        public R getValue() {
            return this.value;
        }
    
        @Override
        @SuppressWarnings("rawtypes")
        public boolean equals(@Nullable final Object object) {
            if (this == object) {
                return true;
            }
            if (object == null) {
                return false;
            }
            if (this.getClass() != object.getClass()) {
                return false;
            }
            final Pair<?, ?> other = (Pair) object;
            return Objects.equals(this.key, other.key) && Objects.equals(this.value, other.value);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(this.key, this.value);
        }
    
        @Override
        public String toString() {
            return String.format("(%s - %s)", this.key, this.value);
        }
    
    }
    

    Following is the result that I use with it that might meet your desired output:

        public static void main(final String[] args) {
            final HashSet<Pair<Integer, String>> pairs = new HashSet<>();
            pairs.add(Pair.of(12, "Hello"));
            pairs.add(Pair.of(12, "Hi"));
            pairs.add(Pair.of(13, "Hello"));
            pairs.add(Pair.of(14, "Hello"));
            pairs.add(Pair.of(15, "Hello"));
            System.out.println(pairs); // => [(13 - Hello), (12 - Hello), (15 - Hello), (14 - Hello), (12 - Hi)]
        }
    

    In case you don't want to create new class. You can use buildin class Entry from Map.

    public static void main(final String[] args) {
        final HashSet<Map.Entry<Integer, String>> pairs = new HashSet<>();
        pairs.add(Map.entry(12, "Hello"));
        pairs.add(Map.entry(12, "Hi"));
        pairs.add(Map.entry(12, "Hi"));
        pairs.add(Map.entry(13, "Hello"));
        pairs.add(Map.entry(14, "Hello"));
        pairs.add(Map.entry(15, "Hello"));
        System.out.println(pairs);
        // [12=Hello, 13=Hello, 14=Hello, 15=Hello, 12=Hi]
    }