【问题标题】:Collection to store objects with combination of ids as unique将具有 id 组合的对象存储为唯一的集合
【发布时间】:2017-03-30 18:24:19
【问题描述】:

我有一个带有属性的类测试

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

因此,每个(id1 和 id2)唯一 id 组合都有一个 stringValues 列表。 我希望能够将其存储在一个集合中。 示例:

  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

期望的最终结果是将对象存储为

-> {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}}

我希望能够将“测试”对象列表存储在集合中。 我尝试了 Set ,覆盖了等号和哈希码,但它没有按预期工作。 给你

@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;
        }
    }

我遍历每个对象并将其存储在一个 SET 中。它确实消除了([id1 和 id2] 的冗余组合,但它也消除了相应的字符串值。) 糟糕,我忘了提到我从从数据库中检索的结果集中获取数据。 所以每一行都包含 id1、id2 和一个字符串值(所有行都不同)。有些行会有一个共同的 id1 和 id2 值

有人可以给我建议吗?

提前谢谢你

【问题讨论】:

  • '没有按预期工作'不是任何人都可以帮助你的,除非你具体描述你尝试了什么,它的行为方式以及它与你的预期有何不同。包含代码。
  • 如果遇到任何错误,请发布堆栈跟踪,因为我认为您的方法是正确的,只是实施可能存在问题
  • 好的,让我发布代码
  • 使用 .equals not == 来比较字符串。并为自己编写一个 3 行测试用例来测试您的 .equals 和 hashCode 是否有效。
  • 再一次,如果您只是编写一个测试用例来查看您的方法是否按照您的想法执行,那么所有这些理论都是不必要的。看起来你写了一个等号和一个哈希码,把东西扔进一个哈希集中,然后惊讶地发现结果是“出乎意料的”。测试你的代码,让一群陌生人在互联网上为你做这件事要慢得多,看不见。

标签: java jakarta-ee collections


【解决方案1】:

这能解决你的问题吗?

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 +
                    '}';
        }
    }
}

输出:

{id{a=1, b=2}=[一, 二],

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

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

id{a=5, b=3}=[四, 六]}

您必须自己弄清楚如何对结果进行排序。

【讨论】:

  • 是的,解释得很好。非常感谢!!
猜你喜欢
  • 2017-02-21
  • 2018-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-06
相关资源
最近更新 更多