连接几个枚举?

发布于 2024-12-18 15:32:18 字数 774 浏览 2 评论 0原文

由于我们的特定需求,我必须对 ResourceBundle 进行子类化。

但是,要覆盖 getKeys(),我有点麻烦。这个 getKeys 需要以某种方式从底层 ResourceBundle 的映射中连接起来。我怎样才能做到这一点?

谢谢

编辑:在提交时我遇到了一个想法。基本上,我们的每个 Module 都有一个 ResourceBundle,所以我的代码到目前为止如下所示:

public Enumeration<String> getKeys() {
        ArrayList<String> keys = new ArrayList<String>();

        for (Map.Entry<Module, ResourceBundle> entry : internalMap.entrySet()) {
            Enumeration<String> tmp = entry.getValue().getKeys();
            while (tmp.hasMoreElements()) {
                String key = tmp.nextElement();
                keys.add(key);
            }
        }

        return Collections.enumeration(keys);
    }

I had to subclass ResourceBundle due to our specific needs.

However, to override getKeys(), I am a bit in trouble. This getKeys needs to somehow concatenate from a map of underlying ResourceBundles. How can I do that?

Thanks

EDIT: While submitting I came across an idea. Basically we have for each of our Module a ResourceBundle, so my code looks like this so far:

public Enumeration<String> getKeys() {
        ArrayList<String> keys = new ArrayList<String>();

        for (Map.Entry<Module, ResourceBundle> entry : internalMap.entrySet()) {
            Enumeration<String> tmp = entry.getValue().getKeys();
            while (tmp.hasMoreElements()) {
                String key = tmp.nextElement();
                keys.add(key);
            }
        }

        return Collections.enumeration(keys);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

℉服软 2024-12-25 15:32:18

最简单的方法就是手动枚举枚举,将它们转储到集合中,然后返回该集合的枚举。

如果做不到这一点,您可以结合 Google Guava 操作来执行此操作,如下所示

// the map of enumerations
Map<?, Enumeration<String>> map = ...

// a function that turns enumerations into iterators
Function<Enumeration<String>, Iterator<String>> eumerationToIteratorFunction = new Function<Enumeration<String>, Iterator<String>>() {
   public Iterator<String> apply(Enumeration<String> enumeration) {
      return Iterators.forEnumeration(enumeration);
   }
};

// transform the enumerations into iterators, using the function
Collection<Iterator<String>> iterators = Collections2.transform(map.values(), eumerationToIteratorFunction);

// combine the iterators
Iterator<String> combinedIterator = Iterators.concat(iterators);

// convert the combined iterator back into an enumeration
Enumeration<String> combinedEnumeration = Iterators.asEnumeration(combinedIterator); 

:相当麻烦,但是 Enumeration 很旧,并且在现代 API 中支持很差。通过明智地使用静态导入,可以稍微缩小它的规模。您甚至可以在单个函数式语句中完成整个操作:

Map<?, Enumeration<String>> map = ...

Enumeration<String> combinedEnumeration = asEnumeration(concat(
   transform(map.values(), new Function<Enumeration<String>, Iterator<String>>() {
      public Iterator<String> apply(Enumeration<String> enumeration) {
         return forEnumeration(enumeration);
      }
   })
)); 

这种方法的优点是高效 - 它会惰性地完成所有操作,并且在您要求之前不会进行迭代。不过,在您的情况下,效率可能并不重要,在这种情况下,只需以简单的方式进行即可。

The simplest approach is just to manually enumerate over the enumerations, dump them into a collection, then return an enumeration of that collection.

Failing that, you could combine Google Guava operations to do this, something like this:

// the map of enumerations
Map<?, Enumeration<String>> map = ...

// a function that turns enumerations into iterators
Function<Enumeration<String>, Iterator<String>> eumerationToIteratorFunction = new Function<Enumeration<String>, Iterator<String>>() {
   public Iterator<String> apply(Enumeration<String> enumeration) {
      return Iterators.forEnumeration(enumeration);
   }
};

// transform the enumerations into iterators, using the function
Collection<Iterator<String>> iterators = Collections2.transform(map.values(), eumerationToIteratorFunction);

// combine the iterators
Iterator<String> combinedIterator = Iterators.concat(iterators);

// convert the combined iterator back into an enumeration
Enumeration<String> combinedEnumeration = Iterators.asEnumeration(combinedIterator); 

It's pretty cumbersome, but Enumeration is old and rather poorly supported in modern APIs. It can be slimmed down a bit by judicious use of static imports. You can even do the whole thing in a single function-style statement:

Map<?, Enumeration<String>> map = ...

Enumeration<String> combinedEnumeration = asEnumeration(concat(
   transform(map.values(), new Function<Enumeration<String>, Iterator<String>>() {
      public Iterator<String> apply(Enumeration<String> enumeration) {
         return forEnumeration(enumeration);
      }
   })
)); 

This approach has the benefit of being efficient - it does everything lazily, and won't iterate until you ask it to. Efficiency may not matter in your case, though, in which case just do it the simple way.

原谅过去的我 2024-12-25 15:32:18

您可以使用 sun.misc.CompoundEnumeration。它是 Java 的一部分,不需要额外的库。

You can use sun.misc.CompoundEnumeration. It is part of Java without the need of additional libraries.

如果没结果 2024-12-25 15:32:18

您可以创建自己的自定义 Enumeration 实现,该实现将具有 addAll (Enumerationenumeration) 方法。然后对所有底层 ResourceBundle 对象调用 getKeys(),并将它们全部添加到您自己的 Enumeration 的新实例中。

You can create your own custom Enumeration implementation that will have a addAll (Enumeration<E> enumeration) method. Then call getKeys() on all underlying ResourceBundle objects, and add them all to a new instance of your own Enumeration.

ι不睡觉的鱼゛ 2024-12-25 15:32:18

您可以使用 Guava 的迭代器类:使用 forEnumeration 转换每个枚举,然后 concat 迭代器,并将生成的迭代器转换回枚举asEnumeration

或者使用类似于 Guava 的 concat 方法的代码自己实现串联枚举。

You could use Guava's Iterators class: transform each Enumeration using forEnumeration, then concat the iterators, and transform the resulting iterator back to an Enumeration using asEnumeration.

Or implement an concatenating Enumeration yourself using code similar to Guava's concat method.

听你说爱我 2024-12-25 15:32:18

这就是我们最终想出的办法。虽然还有更多代码,但我认为分享基础知识是公平的。该解决方案遵循了一点斯卡夫曼的建议。
感谢所有的贡献。

public class ChainedResourceBundle extends ResourceBundle implements Enumeration<String> {

    Iterator<Map.Entry<Module, ResourceBundle>> tables;
    private Enumeration<String>                 keys;

    private Map<Module, ResourceBundle>         internalMap    = new HashMap<Module, ResourceBundle>();
    private Map<String, String>                 customizedKeys = new HashMap<String, String>();


    @Override
    public Enumeration<String> getKeys() {
        tables = internalMap.entrySet().iterator();
        nextTable();
        return this;
    }


    @Override
    public boolean hasMoreElements() {
        return keys != null;
    }


    @Override
    public String nextElement() {
        String key = keys.nextElement();
        if (!keys.hasMoreElements()) {
            nextTable();
        }
        return key;
    }

    private void nextTable() {
        if (tables.hasNext()) {
            keys = tables.next().getValue().getKeys();
        } else {
            keys = null;
        }
    }

}

This is what we finally came up with. There is more code to it but thought it would be fair to share the basics. The solution follows a bit skaffman's proposal.
Thanks to all contributions.

public class ChainedResourceBundle extends ResourceBundle implements Enumeration<String> {

    Iterator<Map.Entry<Module, ResourceBundle>> tables;
    private Enumeration<String>                 keys;

    private Map<Module, ResourceBundle>         internalMap    = new HashMap<Module, ResourceBundle>();
    private Map<String, String>                 customizedKeys = new HashMap<String, String>();


    @Override
    public Enumeration<String> getKeys() {
        tables = internalMap.entrySet().iterator();
        nextTable();
        return this;
    }


    @Override
    public boolean hasMoreElements() {
        return keys != null;
    }


    @Override
    public String nextElement() {
        String key = keys.nextElement();
        if (!keys.hasMoreElements()) {
            nextTable();
        }
        return key;
    }

    private void nextTable() {
        if (tables.hasNext()) {
            keys = tables.next().getValue().getKeys();
        } else {
            keys = null;
        }
    }

}
烦人精 2024-12-25 15:32:18

您还可以使用 Vector

public Enumeration<String> getKeys() {
    ResourceBundle parent = this.parent;
    Set<String> keySet = this.handleKeySet();
    List<String> parentKeySet = (parent != null) ? list(parent.getKeys()) : null;
    keySet.addAll(parentKeySet);
    return new Vector<>(keySet).elements();
}

You can also use Vector like

public Enumeration<String> getKeys() {
    ResourceBundle parent = this.parent;
    Set<String> keySet = this.handleKeySet();
    List<String> parentKeySet = (parent != null) ? list(parent.getKeys()) : null;
    keySet.addAll(parentKeySet);
    return new Vector<>(keySet).elements();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文