Java:从字典中懒洋洋地加载单词:如何使它成为静态的最终版本?

Java:从字典中懒洋洋地加载单词:如何使它成为静态的最终版本?,java,final,Java,Final,我有一个使用单词列表的程序(比如说/usr/share/dict/words中的所有单词)。单词列表从来没有被修改过,所以我想我应该让它成为最终的静态列表。但是我怎样才能使它成为最终的呢?我当前的实现是这样的(我在需要的时候懒洋洋地加载单词列表,尽管我不确定懒洋洋的部分是否必要,因为列表并没有那么大或加载速度慢): 但是这会丢失延迟加载部分(虽然这可能没有作为最终版本那样重要?可能我太努力了,无法“按书”做事?)。您可以使用来自的来防止它被修改 所以你可以这样做: private static

我有一个使用单词列表的程序(比如说/usr/share/dict/words中的所有单词)。单词列表从来没有被修改过,所以我想我应该让它成为最终的静态列表。但是我怎样才能使它成为最终的呢?我当前的实现是这样的(我在需要的时候懒洋洋地加载单词列表,尽管我不确定懒洋洋的部分是否必要,因为列表并没有那么大或加载速度慢):

但是这会丢失延迟加载部分(虽然这可能没有作为
最终版本那样重要?可能我太努力了,无法“按书”做事?)。

您可以使用来自的来防止它被修改

所以你可以这样做:

private static List<String> WORDS;

private static List<String> getWords() throws IOException {
  if (WORDS == null) {
    List<String> words = new LinkedList<String>();
    String line;
    BufferedReader br = new BufferedReader(new FileReader("my_dictionary.txt"));
    while ((line = br.readLine()) != null) {
      words.add(line);
    }
    WORDS = ImmutableList.copyOf(words);
  }
  return WORDS;
}
私有静态列表字;
私有静态列表getWords()引发IOException{
if(WORDS==null){
列表单词=新建链接列表();
弦线;
BufferedReader br=新的BufferedReader(新的文件阅读器(“my_dictionary.txt”);
而((line=br.readLine())!=null){
添加(行);
}
WORDS=不可变列表。copyOf(WORDS);
}
返回单词;
}
您可以使用来自的来防止对其进行修改

所以你可以这样做:

private static List<String> WORDS;

private static List<String> getWords() throws IOException {
  if (WORDS == null) {
    List<String> words = new LinkedList<String>();
    String line;
    BufferedReader br = new BufferedReader(new FileReader("my_dictionary.txt"));
    while ((line = br.readLine()) != null) {
      words.add(line);
    }
    WORDS = ImmutableList.copyOf(words);
  }
  return WORDS;
}
私有静态列表字;
私有静态列表getWords()引发IOException{
if(WORDS==null){
列表单词=新建链接列表();
弦线;
BufferedReader br=新的BufferedReader(新的文件阅读器(“my_dictionary.txt”);
而((line=br.readLine())!=null){
添加(行);
}
WORDS=不可变列表。copyOf(WORDS);
}
返回单词;
}

唯一的方法是将变量设置为静态final,然后在static部分初始化它,如下所示:

static final Collection<String> WORDS;

static {
    try {
        WORDS = new ArrayList<String>();
        // Load dict into variable
    } catch (...) {...}
}
静态最终集合词;
静止的{
试一试{
WORDS=newarraylist();
//将dict加载到变量中
}捕获(…){…}
}
问题是,如果抛出异常,无法判断发生了什么。它将停止执行静态块。如果部分初始化,您将不知道


在单例中设置变量并始终以这种方式获取它可能会更好。这将确保它只初始化一次。

唯一的方法是将变量设置为静态最终变量,然后在静态部分初始化它,如下所示:

static final Collection<String> WORDS;

static {
    try {
        WORDS = new ArrayList<String>();
        // Load dict into variable
    } catch (...) {...}
}
静态最终集合词;
静止的{
试一试{
WORDS=newarraylist();
//将dict加载到变量中
}捕获(…){…}
}
问题是,如果抛出异常,无法判断发生了什么。它将停止执行静态块。如果部分初始化,您将不知道


在单例中设置变量并始终以这种方式获取它可能会更好。这将确保它只初始化一次。

有几件事需要记住:

  • 当您声明列表为final时,只有对象引用本身才是final。列表的内容仍然可以修改。因此,如果您试图阻止列表内容被更改,final对您没有帮助。您将需要某种不可变的集合,比如JIT
  • 您可以在类初始化期间或在构造函数中为最终变量赋值。所以,您可以继续在类初始化时分配一个空列表,然后根据需要延迟加载

    • 有几件事需要记住:

      • 当您声明列表为final时,只有对象引用本身才是final。列表的内容仍然可以修改。因此,如果您试图阻止列表内容被更改,final对您没有帮助。您将需要某种不可变的集合,比如JIT
      • 您可以在类初始化期间或在构造函数中为最终变量赋值。所以,您可以继续在类初始化时分配一个空列表,然后根据需要延迟加载

      在MBCook所说的基础上,如果您确定失败的条件是阻塞的(但必须确实确定),您可以在catch子句中添加一个throw,将异常作为RuntimeException(未选中)抛出。例如,在我的例子中,我有一个服务(延迟加载),如果它抛出一个不可恢复的异常,我不想继续,我想让java关闭(我也想在这里问一下这是否是一种好技术:))


      在MBCook所说的基础上,如果您确定失败的条件是阻塞的(但必须确实确定),您可以在catch子句中添加一个throw,将异常作为RuntimeException(未选中)抛出。例如,在我的例子中,我有一个服务(延迟加载),如果它抛出一个不可恢复的异常,我不想继续,我想让java关闭(我也想在这里问一下这是否是一种好技术:))


      java.util.Collections.unmodifiableList在此上下文中似乎也很好(因为基本列表不会泄漏)。java.util.Collections.unmodifiableList在此上下文中也很好(因为基本列表不会泄漏)。我不确定您在这里从
      final
      中获得了多少好处,因为数据是私有的。也就是说,听起来这里根本不需要惰性初始化(列表不太大)。我会使用您编辑的版本(使用@jits建议使其不可变)。我不确定您从这里的
      final
      中获得了多少好处,因为数据是私有的。也就是说,听起来这里根本不需要惰性初始化(列表不太大)。我会使用您编辑的版本(使用@jits建议使其不可变)。
      static final ServiceClass mLazyService;
      
      static {
          try {
              mLazyService = new ServiceClass ();
          } catch (Exception e) {
              throw new RuntimeException(e);
          }
      }