【问题标题】:Why does set1 get null when set goes null?为什么当 set 为空时 set1 为空?
【发布时间】:2013-02-08 18:17:52
【问题描述】:

在下面的 sn-p 中,我执行一个查询并将结果集传递给set。然后将set 分配给set1。之后有一个while循环,直到set.next返回false。是不是set.next循环后返回false,set1也会返回false?

ResultSet set = statement.executeQuery();
ResultSet set1 = set;
while (set.next()) {
    if (set.getString(1).equalsIgnoreCase(keyword)) { 
        // If the search matches the exact keyword
        list.put(set.getString(2), set.getString(1));
        // Where key is the name of the node and value is, name of the file
    }
}

我问这个是因为:

while (set1.next()) {
    System.out.println("@@@Inside the while statement@@@");
    if (set1.getString(1).contains(keyword) 
    && set1.getString(1).compareToIgnoreCase(keyword) !=0) { 
        // If the search contains the keyword but does not exactly match
        list.put(set.getString(2), set.getString(1));
        // Where key is the name of the node and value is, name of the file
        System.out.println("@@@Inside the if statement of second while loop !@@@");
    }
}

这个while 构造永远不会起作用。是这个原因吗?如果是这样,我该怎么办?

【问题讨论】:

  • 您已经遍历了 ResultSet。请理解,虽然您有两个 ResultSet 变量,但它们都指向同一个 ResultSet object。因此,如果您已遍历对象并在一个变量上调用 next() 返回 false,那么无论您在哪个变量上调用该方法,它都会为 false。
  • @HovercraftFullOfEels 但我在迭代之前将set 分配给set1
  • 没关系。同样 set 和 set1 指的是同一个对象。
  • @HovercraftFullOfEels 那么有没有办法复制对象以保持他们的灵魂不同?

标签: java database jdbc


【解决方案1】:

您有两个主要错误:

  1. set 分配给set1 不会复制 - 这是同一组
  2. String.contains() 区分大小写(您的代码与您的 cmets 不匹配)

解决方法是:

  1. 不要使用两个循环 - 只使用一个循环
  2. 使用`toLowerCase()contains() 来实现“不区分大小写的包含”测试
  3. 另外,如果您的第一个测试为真,那么您的第二个测试也是如此,因此您不需要两个测试/循环

试试这个代码:

   ResultSet set = statement.executeQuery();
   while(set.next()) {
       if(set.getString(1).toLowerCase()
              .contains(keyword.toLowerCase)) {
           list.put(set.getString(2), set.getString(1));
       }
   }

另外,不要将地图称为“列表” - 将其称为“地图”,否则只会让代码的读者感到困惑。

【讨论】:

    【解决方案2】:

    你可以试试这个。

       ResultSet set1 = statement.executeQuery();
    

    【讨论】:

      【解决方案3】:

      set1 是对set 指向的同一对象的引用。如果你想再次迭代 ResultSet,你需要使用类似的方式将迭代器光标再次移动到开头:

      set.beforeFirst();
      

      在 Java 中,将变量分配给对象不会复制对象,它只会引用内存中的对象。如果您希望 setset1 独立工作,则必须显式复制该对象。

      在您的特定用例中,我认为这不是您想要的,只是移动迭代光标似乎更好。

      【讨论】:

      【解决方案4】:

      是不是如果set.next循环后返回false,set1也会 返回假?

      是的。因为set1 指的是Resultset 的同一个对象,set 指的是同一对象。因此,set 引用的ResultSet 对象所表现出的任何行为也将由set1 反映。在您的第一个while 循环中,set 引用的ResultSet 对象在迭代所有记录后完全耗尽(使用set.next()) 。此后,无论哪个变量(set 或 set1)尝试读取更多内容,都将得到 .next()false

      如果在您的第​​一个 while 循环构造中,我使用 set 变量检查 .next() 并使用 set1 变量获得结果,它仍然可以工作。 试试这个代码而不是你的第一个构造,你会看到输出和你在第一个 while 构造中写的一样:

      ResultSet set = statement.executeQuery();
             ResultSet set1 = set;
             while(set.next()) {
                 if(set1.getString(1).equalsIgnoreCase(keyword)) { // If the search matches the exact keyword
                     list.put(set1.getString(2), set1.getString(1));
                     // Where key is the name of the node and value is, name of the file
                 }
             }
      

      如果您仍然希望set1 返回结果,您应该使用以下方法重构一个新的ResultSet 对象:

      set1 = stat.executeQuery()
      

      其中,stat 是您在代码中使用的 Statement/PreparedStatement

      【讨论】:

        猜你喜欢
        • 2010-12-08
        • 1970-01-01
        • 2016-06-20
        • 1970-01-01
        • 2019-09-14
        • 2011-05-22
        • 2011-05-22
        • 1970-01-01
        • 2013-10-30
        相关资源
        最近更新 更多