GSON -将ArrayList序列化为包含JSON对象的JSON数组,不包含重复项

fquxozlt  于 2022-11-06  发布在  其他
关注(0)|答案(2)|浏览(194)

我目前正在用JSON在java中创建一个新颖的阅读器/编辑器。我已经创建了阅读器部分,没有任何问题,但是编辑器中的JSON序列化给我带来了一些问题。我们的想法是向ArrayList添加或设置一个对象,如下所示:

ArrayList<Chapters> allChapters = new ArrayList<>();

private void TAContentKeyTyped(java.awt.event.KeyEvent evt) {                                   
    Chapters newChapter = new Chapters(LSChapters.getSelectedValue(), TAContent.getText());
    if (allChapters.contains(newChapter)) {
        allChapters.set(0, newChapter);
    }
    else {
        allChapters.add(newChapter);
    }
    String json = gson.toJson(allChapters);
    Iterator allChaptersIterator = allChapters.iterator();
    while (allChaptersIterator.hasNext()) {
        System.out.println(allChaptersIterator.next().toString());
    }
    System.out.println(json);
}

当我按三次退格键时,它会输出这个:

Chapter: Test Content: 
Chapter: Test Content: 
Chapter: Test Content: 
[{"chapter":"Test","content":""},{"chapter":"Test","content":""},{"chapter":"Test","content":""}]

正如您所看到的,尽管在if上放置了一个.contains()方法,但代码每次都使用.add()方法而不是.set()方法,而不是将所有具有相同章节名称的输入放入一个元素中。诚然,我并不期望这种方法能起作用,但我完全不知道如何处理这种方法。
所需的输出应如下所示:

Chapter: Test Content: This is content 1
Chapter: Test 2 Content: This is content 2
[{"chapter":"Test","content":"This is content 1"},{"chapter":"Test 2","content":"This is content 2"}]

其中具有相同名称的每一章都存储在单个元素中,无论按下了多少个键。
先谢谢你了。

Chapters类如下所示:

public class Chapters {
    private String chapter;
    private String content;

    public Chapters(String chapter_name, String chapter_content) {
        chapter = chapter_name;
        content = chapter_content;
    }

    @Override
    public String toString() {
        return "Chapter: " + chapter + " Content: " + content;
    }
}

**注意:**请忽略.set()方法使用索引0,这只是为了测试。真实的的函数将使用章节名称的索引。

iqjalb3h

iqjalb3h1#

也许您应该使用Set而不是List?更改您的

ArrayList<Chapters> allChapters = new ArrayList<>();

至-例如:

Set<Chapters> chapters = new HashSet<>();

要使Set正确运行,还应该在Chapters中实现equals(..)hashCode(),例如,如果您只能依赖chapter

@Override
public int hashCode() {
    return chapter.hashCode();
}

@Override
public boolean equals(Object obj) {
    if (obj != null) {
        if (obj instanceof Chapters) {
            return chapter.contentEquals(((Chapters) obj).getChapter());
        }
    }
    return false;
}

不再需要显式地检查重复。您可以只将章节添加到您的集合中,以上更改将确保没有重复。

iezvtpos

iezvtpos2#

原来主要的问题是键盘事件。无论我使用哪个侦听器(KeyPressed、KeyReleased、KeyTyped),总会弹出某种索引错误。我最终让步了,给了这个函数自己的按钮。现在它工作得很好。下面是新代码:

try {
      String contentString = TAContent.getText();
      int contentStringLen = contentString.length();
      int selectedIndex = LSChapters.getSelectedIndex();
      int ArrayIndexLength = sessionContent.size();

      if (contentStringLen > 1) {
        if (ArrayIndexLength < selectedIndex) {
          for (int i = 0; i < selectedIndex; i++) {
            sessionContent.add(0, "");
          }
        }

        if (selectedIndex >= ArrayIndexLength) {
          sessionContent.add(selectedIndex, contentString);
        }
        else {
          sessionContent.set(selectedIndex, contentString);
        }
      }
      else {
        JOptionPane.showMessageDialog(null, "Please write chapter content first!");
      }
    }
    catch (Exception e) {
      System.err.println(e);
    }

相关问题