【问题标题】:Retrieving data in a map在地图中检索数据
【发布时间】:2020-08-26 22:50:26
【问题描述】:
public class Dashboard {
int REQUEST_ID, PRICE, Status;           
String LOGIN_USER;

public int getREQUEST_ID() {
 return REQUEST_ID;
 }

 public void setREQUEST_ID(int rEQUEST_ID) {
  REQUEST_ID = rEQUEST_ID;
 }

  //all getters and setters
  public class MapKey {
  private Integer id;
  private String name;

   public MapKey(Integer id, String name) {
    this.id = id;
    this.name = name;
  }

  @Override Hashcode and equals
public class DBConnection {
 public ArrayList<Dashboard>  getStoreResult() {
   ArrayList<Dashboard> dashRec;

 try{
  Class.forName("");
  Connection con=DriverManager.getConnection("");
  Statement st=con.createStatement();
  ResultSet rs=st.executeQuery("");

  HashMap<Object, List<Dashboard>> map = new HashMap<>();
  HashMap<Integer, Integer> mapStatus = new HashMap<>();
  while (rs.next()) {
    Integer id = rs.getInt(1);
    MapKey key = new MapKey(rs.getInt(1), rs.getString(2));
    if (!map.containsKey(key)) {
        dashRec= new ArrayList<Dashboard>();
        map.put(key, dashRec);
    }
    Dashboard dash = new Dashboard();
    dash.setREQUEST_ID(id);
    dash.setLOGIN_USER(rs.getString(2));
    dash.setPRICE(rs.getInt(3));
    dash.setStatus(rs.getInt(4));/////STATUS
    map.get(id).add(dash);
    if (!mapStatus.containsKey(id) || mapStatus.get(id)>dash.getPROCESSED()){
                mapStatus.put(id, dash.getPROCESSED());
            } 
    }
   }
  }
 }

我想创建一个新的Hashmap,键为req_id+name+特定集合的最低状态编号。这里的集合是指特定ReqId的行数。例如:对于 reqid 123,我们有 7 行构成一个集合。最低状态号是 1.所以值键将是 123 A 1.类似地,对于键 456,我需要值 456 B 2.所以对于示例数据哈希图必须包含 3 个具有 3 个值的键。我想要 n 个 Reqid。每个键的值是 arraylist,它由作为对象的特定 id 的行组成。值在代码中定义。

我只想改变地图的键。

【问题讨论】:

  • req 123 名称为 A 有 2 次出现状态 1。您如何区分使用哪一个?
  • 它可以是无穷无尽的。我只需要一个最低的。所以我们需要检查每个出现的状态号。我们比较它们中的每一个并从中得到最低的。
  • 它不像一个特定的使用。我只需要最低的编号。即 123 reqid,它是 1。
  • 使用“最低状态”作为键的一部分是没有意义的。 “最低”是什么?也许,您希望将 req_id 和 name 作为键,但只保留那些状态等于所有具有相同 req_id 和 name 的值的最低状态的值?还是您只想将“状态”作为键的一部分?
  • “显示最低状态”和将最低状态作为键的一部分是有区别的。具有不同状态值的 Dashboard 实例应该如何处理?

标签: java sql object collections hashmap


【解决方案1】:

先在外循环创建地图

Map<Integer, Integer> mapStatus = new HashMap<>();

并在循环中检查和更新地图以获取新的 ID 集或较大的现有状态

while (rs.next()) {
    ... // your existing codes
    if (!mapStatus.containsKey(id) || mapStatus.get(id)>dash.getStatus()) {
        mapStatus.put(id, dash.getStatus());
    } 
}

【讨论】:

  • 我调用了在仪表板类中定义的 setstatus 函数。rs.getInt(4) 被传递给它。然后我将该状态添加到已经存在的地图中。所以在我添加破折号对象后检查这个 if 条件进入地图?
  • 已更新。只需在将破折号对象添加到地图后添加 if 条件即可。并创建mapStatus外循环
  • 这个if放在添加dash对象到map之前还是之后都没有关系,只要放在dash.setStatus之后。否则,您实际上可以将rs.getInt(4) 存储在status 变量中,并将其用于dash.setStatus(status)if
  • @VSSCHAITANYAChavali 我明白了兄弟。
  • 语句if (!mapStatus.containsKey(id) || mapStatus.get(id)&gt;dash.getStatus()) { mapStatus.put(id, dash.getStatus()); }可以简化为单语句mapStatus.merge(id, dash.getStatus(), Math::min);同理,对于另一张图(更新的问题),可以使用map.computeIfAbsent(key, xKey -&gt; new ArrayList&lt;&gt;()).add(dash);,只放一个新的ArrayList必要时将新元素添加到列表中。
【解决方案2】:

你的主循环归结为

HashMap<Object, List<Dashboard>> map = new HashMap<>();
HashMap<Integer, Integer> mapStatus = new HashMap<>();
while(rs.next()) {
    Integer id = rs.getInt(1);
    String user = rs.getString(2);
    Dashboard dash = new Dashboard();
    dash.setREQUEST_ID(id);
    dash.setLOGIN_USER(user);
    dash.setPRICE(rs.getInt(3));
    dash.setStatus(rs.getInt(4));
    map.computeIfAbsent(new MapKey(id, user), xKey -> new ArrayList<>()).add(dash);
    mapStatus.merge(id, dash.getPROCESSED(), Math::min);
}

computeIfAbsent 将返回一个现有值或使用函数计算一个值以将其存储在映射中并返回。无论哪种情况,您都可以简单地将add 应用于返回的列表。

merge 如果不存在值,则只会将指定的值放入映射中,否则将使用指定的函数从旧值和新值中计算出一个值。由于Math.min(…,…) 将简单地返回两个值中较小的一个,这将是要存储或保存在地图中的值。

请注意,在您问题的代码中,密钥的使用不一致。您在必要时使用map.put(key, dashRec); 存储新列表,但map.get(id).add(dash); 检索列表并添加到它。使用computeIfAbsent 方法,不可能在密钥上不一致。此外,dashRec 变量已过时。

顺便说一句,当MapKey 不携带额外的语义时,已经有其他类型能够实现该目的。例如。您可以使用Array.asList(id, user),或者,当您使用Java 9+ 并且可以排除null 值时,List.of(id, user)。或new AbstractMap.SimpleImmutableEntry(id, user)。所有这些类型都实现了适当的equals/hashCode 方法。

Array.asList(…) 的优点是可以扩展到更多组件,SimpleImmutableEntry 为恰好两个组件提供了有效的存储。 Java 9 的 List.of(…) 方法结合了两者,它允许更多组件,但返回针对少量组件的优化实现。但它禁止null 元素。

【讨论】:

  • 我想输出如下内容:
  • MapKey [reqid=123, name=A,status=1]:[Dashboard [reqid=123, NAME=A, PRICE=5,STATUS=2],Dashboard [reqid=123, NAME =A, PRICE=10,STATUS=3],...,..] MapKey [reqid=456, name=B,status=2]:[Dashboard [reqid=456, NAME=B, PRICE=20,STATUS =3],Dashboard [reqid=456, NAME=B, PRICE=25,STATUS=2],...,..] 对于 N 行相同的输出
  • 我想要一张地图。请在我更新后参考问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-26
  • 2021-08-04
  • 2021-12-07
  • 2020-11-21
  • 2020-07-07
  • 1970-01-01
相关资源
最近更新 更多