【问题标题】:Strange behaviour of ArrayListArrayList 的奇怪行为
【发布时间】:2009-06-06 03:30:47
【问题描述】:

我正在使用 JSP、JSTL、Servlet 和 JavaBeans 编写网站。

在我的代码中,我尝试使用对象的 ArrayList,但发生了一件奇怪的事情:当我添加第一个对象时它很好,当我添加第二个对象时它会在第二个对象中添加它位置,但 index(0) 处的对象与 index(1) 处的对象获得相同的值。

可能问题出在

ArrayList<Article> articleList = new ArrayList<Article>();
Article newArticle = new Article();

由于articleList是Article类的ArrayList。

谁能指出我做错了什么?

下面是我的代码:

public ArrayList<Article> getArticles()
{
    baseIO mySql = new baseIO();
    ArrayList<Article> articleList = new ArrayList<Article>();
    int articleId = 0;

    try
    {
        String sql =
            "select * from jsp_blog_article order by article_id Desc Limit 3";
        con = (Connection)mySql.getConnection();
        pstmt = (PreparedStatement) con.prepareStatement(sql);
        ResultSet rs = pstmt.executeQuery();
        while (rs.next()) {
            Article newArticle = new Article();
            newArticle.setArticleAuthor(rs.getString("article_name"));
            newArticle.setArticleBody(rs.getString("article_body"));
            newArticle.setArticleAuthor(rs.getString("article_author"));
            newArticle.setArticleDate(rs.getString("article_date"));
            articleId = Integer.parseInt(rs.getString("article_id"));
            newArticle.setArticleId(String.valueOf(articleId));
            newArticle.setArticleComments(this.getCommentsNum(articleId));
            articleList.add(newArticle);
        }
        con.close();
        pstmt.close();
    }
    catch(Exception e)
    {
        return null;
    }

    return articleList;
}

还有文章类

package objects;

import java.io.Serializable;

public class Article implements Serializable{
    private String articleName;
    private String articleBody;
    private String articleAuthor;
    private String articleComments;
    private String articleDate;
    private String articleId;

    public Article()
    {

    }

    // all the getters and setters in place, but it is too long
    // so i am not going to post them in forum

}

【问题讨论】:

  • 您首先解析 articleId 然后立即将其转换回字符串的任何特殊原因?
  • 是复制粘贴getArticles()方法还是你的真实代码略有不同?因为您的代码和 Soldier.moth 的代码之间应该没有功能差异。你每次都在创建一个新的 Article 对象,就像他一样。
  • 我其实也很好奇,因为回首往事,我不确定为什么我的代码在你的代码中没有工作。
  • mmyers,articleId 在 mysql 数据库中是整数,在文章对象中是字符串。当我编写我的代码时,它看起来是正确的,但是 Soldier.moth 的代码有效,而我的无效。数组列表返回到另一个 javabean 并从那里返回到我用 jstl foreach 标记显示它的 jsp 页面。
  • articleId 如何存储在数据库中并不重要。上面的代码从数据库中读取一个字符串(JDBC 驱动程序为您将整数转换为字符串),然后您将字符串转换为 int。然后将 int 转换回字符串。只需使用:newArticle.setArticleId(rs.getString("article_id"));

标签: java jsp jstl javabeans


【解决方案1】:

我会尝试这种方式,看看会发生什么。

int x = 0;
while (rs.next()) {
    articleList.add(new Article());
    articleList.get(x).setArticleName(rs.getString("article_name"));
    articleList.get(x).setArticleBody(rs.getString("article_body"));
    articleList.get(x).setArticleAuthor(rs.getString("article_author"));
    articleList.get(x).setArticleDate(rs.getString("article_date"));
    articleList.get(x).setArticleId(rs.getString("article_id"));
    articleList.get(x).setArticleComments(this.getCommentsNum(articleId));
    x++;
}

【讨论】:

  • 成功了!!!但我不明白为什么。如果您能解释原因,我将不胜感激。
  • 当你这样做时,你每次都在处理一个不同的文章对象,而你这样做的方式你指的是同一个对象,所以当你第二次改变它时,你也在改变第一个。
  • 呃,不。这种方式应该与第一种方式相同,除了在每个 setXXX 方法上从列表中检索文章的额外开销。
  • 我不知道,但是当我发现问题时,我开始调试,它表明当我第一次将 Article 对象放入列表时它运行良好,但是当我开始阅读新文章时对象为下一次添加到列表中,它会改变已经在列表中的对象的属性。
  • 抱歉,这不是答案——Java 是按值传递的,所以当 newArticle 传递给列表的 add 方法时,传递的是文章的引用值(指针),而不是引用自身。所描述的行为可能发生的唯一方法是如果 newArticle 被分配在结果集循环之外。
【解决方案2】:

您两次调用 newArticle.setArticleAuthor...我知道这不是您的列表问题的一部分,但这是一个观察结果。

【讨论】:

    【解决方案3】:

    应该按照其他 cmets 清理代码,但从功能上讲,它应该可以工作。

    这就是我认为正在发生的事情。

    您的代码中有以下两行:

    newArticle.setArticleAuthor(rs.getString("article_name"));
    newArticle.setArticleAuthor(rs.getString("article_author"));
    

    并且没有相应的调用:

    newArticle.setArticleName(rs.getString("article_name"));
    

    这意味着您的对象没有指定文章名称(即使指定了作者)。我敢打赌,在您显示以某种方式合并同名文章的列表之前,您正在做某种处理。

    作为一种通用的调试方法,我建议您模拟您的代码,以便您可以在调试器中运行它并查看实际发生的情况(现在,您的系统有很多移动部件,很难你要磨练实际的问题)。

    在当前情况下,这就像在 Web 容器外运行一个方法一样简单,并使用调试器查看列表中返回的对象。您会发现列表中的对象确实是独立的对象 - 只是具有相同的 articleName 属性。

    【讨论】:

    • 我在此处发布代码后几乎立即修复了 setArticleName。该应用程序是一个博客网站,我只是试图从数据库中读取数据,然后在主页上使用 jstl foreach 显示它。
    • 如果你在调试器中做一个停止点,列表中的记录是什么样的?士兵.moth 的解决方案应该与您的解决方案没有什么不同(除了效率较低且代码有点不漂亮)。真正了解您遇到的问题可能非常重要。
    【解决方案4】:

    代码看起来不错,您如何显示使您认为两个索引处具有相同值的列表?也许您的问题在于该代码。

    【讨论】:

    • 我调试了它,亲眼看到它在运行时是如何变化的。
    【解决方案5】:

    您是否在阅读文章的同时将文章添加到数据库中?我认为,根据您的存储引擎,您可能会在更新过程中遇到阅读问题。

    【讨论】:

    • 我正在使用 mysql。不,我在阅读时没有更新。我只是阅读并显示
    猜你喜欢
    • 2013-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多