当前位置: 首页 > 知识库问答 >
问题:

用于在集合或列表和其他对象中保存值的Java接口

蔡辰钊
2023-03-14

我想编写一个程序,在这个程序中,用户可以决定在什么对象中存储值。用户可以使用集合、列表和文件(例如,Txt、Xml)。我想写一个接口,在那里最终用户选择哪一个(“storage-”)对象并不重要,这样我就不必为每一个决策都编写相同的方法。

我应该如何为它制作一个接口?接口的方法是否足够合适?我还需要做什么/考虑什么?

import java.io.File;
public class StoreValues implements SaveInGeneral<SomeObject>{

          //user's decision (LinkedList, Set or File)

          if(decision == 1){
              SaveInGeneral<SomeObject> obj = new LinkedList<>();
          }
          if(decision == 2){
               SaveInGeneral<SomeObject> obj = new File();
          }
          //...

          obj.add(someObject);
}    

共有1个答案

梁丘安晏
2023-03-14

saveingeneral不适合常见的命名策略,这些策略涉及尝试用名词命名事物。例如,我称之为存储

泛型在这里似乎没有什么用处--关键是要抽象出底层存储机制是什么。所以把它扔掉。

然后,只需定义“保存对象”的确切含义。例如,列表可以存储项目(.add(newItem)),但您可以通过索引(.get(5))检索项目,创建一个迭代器(使用.iterator()),以便您可以通过它对(String v:List)进行.add(newItem),并询问它的大小(.size())等。

你在寻找什么样的原语?

如果这只是存储对象而不是其他,那么您要查找的唯一方法就是.store(ObjectO)

问题是,任务:“在磁盘上存储任意对象”就是不起作用。大多数对象根本无法存储到磁盘。我强烈建议您将.store()方法限制为只允许您知道如何存储的东西。您可以使用Serializable,但这是一个巨大的蠕虫罐头(Serializable是非常复杂的),或者您需要涉及第三方库,如jackson,试图将对象编入JSON或XML。

然后,您需要考虑各种目标平台(文件、数据库、列表、集合等)的需求,并将其与需要存储东西的代码的需求进行交叉。找到子集,使它仅由在所有目标存储机制中实现的可行的东西组成,并且对于需要存储后端的代码来说,这些东西是足够的。

这会很快变得复杂。例如,当读出jackson公司生产的JSON时,您需要提供您想要将JSON读入哪个类,这不是lists需要的东西(它们知道自己已经存储了哪种对象)。反过来,文件也不喜欢这样,如果你一直写一小块数据,然后关闭文件,然后再打开它--开销意味着:

  • 循环1000次并执行以下操作:打开文件,写入50字节的数据,关闭文件。

速度大约慢1000倍vs:

  • 打开文件,循环1000次并执行:写入50字节的数据。然后关闭文件。

换句话说,您必须更新API以包括打开和关闭步骤,或者接受基于文件的存储后端非常慢(1000x)的事实。

下面是最简单的方法--让我们只存储字符串,因为它很容易发送到任何东西,从DBs到文件到列表到网络套接字,现在让我们接受一个低效的算法:

public interface Storage {
    public void store(String data) throws IOException;
}

某些实现:

public class ListBasedStorage implements Storage {
    private final List<String> list = new ArrayList<String>();

    public List<String> getBackingList() {
        return list;
    }

    public void store(String data) {
        list.add(data);
    }
}

public class FileBasedStorage implements Storage {
    private final Path target;
    private static final Charset CHARSET = StandardCharsets.UTF_8;

    public FileBasedStorage(Path p) {
        this.target = target;
    }

    public void store(String data) throws IOException {
        String line = data.replaceAll("\\R", " ") + "\n";
        Files.write(target, line, CHARSET, StandardOpenOption.APPEND);
    }
}

并使用此:

public static void main(String[] args) throws Exception {
  Storage storage = new FileBasedStorage(Paths.get("mydata.txt"));
  new MyApp().sayHello(storage);
}

public void sayHello(Storage storage) throws IOException {
  storage.store("Hello!");
  storage.store("World");
}

然后,您可以通过添加更多的数据类型,或者使用JSON和JSON编组器(如jackson)将这些数据转换为可以放入文件或db中的内容,从而开始使问题复杂化,添加检索代码(其中还可以询问存储包括多少条目,例如要求迭代器遍历数据等),并添加一种两层方法,向存储请求一个“会话”,必须使用try(Session Session=storage.start()){})安全关闭该“会话”,以便快速写入文件和数据库(文件和数据库都是事务性的,也就是说,如果您显式地启动、执行任务,然后保存刚才所做的所有操作,它们会工作得更好)。

 类似资料:
  • 问题内容: 一个简单的问题,Java中的列表是否按值或引用保存对象?如果我将一个对象放在列表中,然后再更改其值之一,列表中的那个对象将具有更新后的值吗? 问题答案: Java中的列表是否按值或引用保存对象? 该 列表 是一个包含对象引用的有序集合。 如果我将一个对象放在列表中,然后再更改其值之一,列表中的那个对象将具有更新后的值吗? 您只能更改/更新 可变 对象。您无法通过它们的引用更新 不可变

  • 我最近接触了Java 8和它的Stream API,最近又接触了它的Collectors API,我发现它有潜力对Stream进行很多很多的转换,但我有一个情况,我不确定Java 8是否可能,甚至根本不可能。我有两个类: 我想知道是否可以从ClassA对象列表中生成一个ClassB对象的分组列表,该列表的值是从ClassA的字段中计算出来的。具体而言: 通过group和ID组合对类进行分组 当关键

  • 问题内容: 扩展这个问题,我接受了一个答案,该答案说在这种情况下 使用查找表或哈希映射 ,因为它是 处理多个条件 的更好的 构造 。 当前构造。 用于存储消息的类。 条件并显示来自上述类的正确消息。 我实际上想知道在这种情况下查找表有什么帮助? 应该如何在Java Hashmap / Hashtable等中实现它,如何具有优势? - - 编辑 - - 我要去@assylias anwer,因为它更

  • 问题内容: 我只想将对象推入mongodb中的对象数组 并将对象推入需要执行的上述文档中 那么我如何使用 mgo驱动程序* 实现相同的功能 * 问题答案: 请尝试以下操作:

  • 我已经浏览了Python文档提供的信息,但我仍然有点困惑。有人可以发布示例代码来编写一个新文件,然后使用pickle将字典转储到其中吗?

  • 我正在尝试编写一个代码,从ArrayList的实例中移除某些对象。 体系结构: null null 代码: