0
votes

I have a class Test with attributes

--> Integer id1
--> Integer id2
--> String stringValue.

So there are list of stringValues per (id1 and id2) combination of unique ids. I want to be able store that in a collection. Example:

  test1 : id1 = 1, id2 = 2 , stringValue = one
  test11 : id1 = 1, id2 = 2 , stringValues =two
  test111 : id1 = 1, id2 = 3 , stringValues =three
  test2 : id1 = 5, id2 = 3, stringValues = four
  test22: id1 = 5, id2 = 2, stringValues = five
  test222: id = 5, id2 = 3, stringValues = six

Desired end result is store the objects as

-> {id = 1, id = 2, String = {one, two} } 
-> {id = 1 , id =3 , String = {three}}
-> {id = 5, id = 3 , String = {four,six}}
-> {id = 5, id = 2 , String = {five}}

I want to be able to store the list of 'test' objects in a collection. I tried Set<> , overriding the equals and hashcode but it didnt work as expected. Here you go

@Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id1 == null) ? 0 : id1.hashCode());
        result = prime * result + ((id2 == null) ? 0 : id2.hashCode());
        return result;
    }


        @Override
    public boolean equals(Object obj) {
        if( obj instanceof Test){
            Test test = (Test) obj;
            return (test.id1 == this.id1 && test.id2 == this.id2);
        } else {
            return false;
        }
    }

I loop through each object and store it in a SET. it does eliminate (redundant combination of [id1 and id2], but it also eliminates the respective string value.) Oops I forgot to mention I get the data from a resultset retrieved from database. so each row consists of id1, id2 and a string value(which is different for all rows). some rows will have a common id1 and id2 values

Can someone please suggest me with any pointers please ?

Thank you in advance

1
'Didn't work as expected' is not something anyone can help you with unless you specifically describe what you tried, how it behaved and how that's different from what you expected. Include code.pvg
Please post the stacktrace if any error is encountered as i feel your approach is correct just there might be problem with the implementationRahul Singh
ok let me post the codeuser2988851
use .equals not == to compare strings. And write yourself a 3 line test case to test your .equals and hashCode actually work.pvg
And again, all of this theory is unnecessary if you'd simply write a test case to see if your methods do what you think they do. It seems like you wrote an equals and a hashcode, threw stuff into a Hashset and then were surprised the result was 'unexpected'. Test your code, it's much slower to have a bunch of strangers on the internet do it for you, sight unseen.pvg

1 Answers

1
votes

Does that solve your problem?

import java.util.*;

public class Playground1 {
    public static void main(String[] args) {

        // fake resultset
        List<DBResultSetRowEmulation> resultSetEmulation = new ArrayList<>();
        resultSetEmulation.add(new DBResultSetRowEmulation(1, 2, "one"));
        resultSetEmulation.add(new DBResultSetRowEmulation(1, 2, "two"));
        resultSetEmulation.add(new DBResultSetRowEmulation(1, 3, "three"));
        resultSetEmulation.add(new DBResultSetRowEmulation(5, 3, "four"));
        resultSetEmulation.add(new DBResultSetRowEmulation(5, 2, "five"));
        resultSetEmulation.add(new DBResultSetRowEmulation(5, 3, "six"));

        Map<DoubleIndex, List<String>> resultData = new HashMap<>();

        // iterate through resultset
        for(DBResultSetRowEmulation row: resultSetEmulation) {
            DoubleIndex curRecordIdx = new DoubleIndex(row.a, row.b);
            if (resultData.containsKey(curRecordIdx)) {
                // append current string to some existing id1+id2 combination
                resultData.get(curRecordIdx).add(row.c);
            } else {
                // create a new list for new id1+id2 combination
                resultData.put(curRecordIdx, new ArrayList<>(Collections.singletonList(row.c)));
            }
        }

        System.out.println(resultData);
    }

    private static class DBResultSetRowEmulation {
        Integer a, b;
        String c;

        DBResultSetRowEmulation(Integer a, Integer b, String c) {
            this.a = a;
            this.b = b;
            this.c = c;
        }
    }

    private static class DoubleIndex {
        private Integer a,b;

        public DoubleIndex(Integer a, Integer b) {
            this.a = a;
            this.b = b;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            DoubleIndex that = (DoubleIndex) o;

            return a.equals(that.a) && b.equals(that.b);
        }

        @Override
        public int hashCode() {
            int result = a.hashCode();
            result = 31 * result + b.hashCode();
            return result;
        }

        @Override
        public String toString() {
            return "id{" +
                    "a=" + a +
                    ", b=" + b +
                    '}';
        }
    }
}

output:

{id{a=1, b=2}=[one, two],

id{a=1, b=3}=[three],

id{a=5, b=2}=[five],

id{a=5, b=3}=[four, six]}

You will have to figure out how to sort that result by yourself.