在Java中使用不同的键搜索对象 - java

我是一名从C ++过渡到Java的开发人员,所以我仍然不具备完成Java Way所需的全部专业知识。
我有以下课程

class Site
{
   String siteName;
   Integer siteId;
   Integer views;
   Integer searches;
}

我维护了2张地图以搜索此类的对象(使用sitename或siteid)

HashMap<String, Site> siteNameToSiteMap;
HashMap<Integer, Site> siteIdToSiteMap;

但是,接下来,我必须在类Site中添加一个名为parentBrand的字段。这将迫使我创建另一个地图以便能够对其进行搜索。

HashMap<String, Site> parentBrandToSiteMap;

这样的“索引”变量可能会增加,从而也增加了我维护的地图数量。

我记得在C ++开发中解决类似问题时使用了Boost Multi-indexed容器。我可以使用Java中一个等效的,受良好支持的,文档齐全的库吗?如果没有,有没有一种方法可以重构我的代码来解决我的问题。

参考方案

我很惊讶没有可用的boost multi-index容器版本。 (也许在某处……)但是,用Java连接您自己的版本并不是很困难。

粗略但可行的版本可能如下所示:

基本站点对象

我使用了一个稍有不同的Site对象,只是为了使事情保持简单(并且因为我没有访问公共汽车上的这篇文章……)

    public class Site {
        Integer id;
        String name;
        String rating;
        // .. Constructor and toString removed for brevity
    }

包装版本

稍后我将介绍一些主力课程,但它们有些难看。这只是为了展示最终的界面,将其包装一小会后的样子:

class SiteRepository { 
   private final MultiMap<Site> sites = new MultiMap<>();
   public final AbstractMap<String, Site> byName = sites.addIndex((site)->site.name);
   public final AbstractMap<Integer,Site> byId = sites.addIndex((site)->site.id);
   public final AbstractMap<String,List<Site>> byRating = sites.addMultiIndex((Site site)->site.rating);
   public void add(Site s) { sites.add(s); }
}

SiteRepository repo = new SiteRepository();
repo.add(...);
Site site = repo.byId.get(1234);
repo.byId.forEach((Integer id, Site s) -> System.err.printf("   %s => %s\n", id, s));

MultiMap核心

可能应该称为MultiIndex,因为MultiMap表示其他含义...

    public static class MultiMap<V> {

        public static class MultiMapIndex<K,V> extends AbstractMap<K,V> {
            @Override
            public Set<Entry<K, V>> entrySet() {
                return map.entrySet();
            }
            HashMap<K,V> map = new HashMap<>();
       }


        public <K> MultiMapIndex<K,V> addIndex(Function<V, K> f) {
            MultiMapIndex<K,V> result = new MultiMapIndex<>();
            Consumer<V> e = (V v) -> result.map.put(f.apply(v), v);
            mappers.add(e);
            values.forEach(e);
            return result;
        }

        public <K> MultiMapIndex<K,List<V>> addMultiIndex(Function<V, K> f) {
            MultiMapIndex<K,List<V>> result = new MultiMapIndex<>();
            Consumer<V> e = (V v) -> {
                K key = f.apply(v);
                List<V> list = result.map.get(key);
                if (list == null) {
                    list = new ArrayList<>();
                    result.map.put(key, list);
                }
                list.add(v);
            };
            mappers.add(e);
            values.forEach(e);
            return result;
        }

        public void add(V v) {
            values.add(v);
            mappers.forEach( e -> e.accept(v));
        }

        private List<Consumer<V>> mappers = new ArrayList<>();
        private List<V> values = new ArrayList<>();    
    }

更多低级示例

    public static void main(String[] args) {
        // Create a multi-map
        MultiMap<Site> multiMap = new MultiMap<>();

        // Add an index by Site.id
        MultiMapIndex<Integer, Site> byId = multiMap.addIndex((site)->site.id);

        // Add some entries to the map
        multiMap.add(new Site(1234,"A Site","A"));
        multiMap.add(new Site(4321,"Another Site","B"));
        multiMap.add(new Site(7777,"My Site","A"));

        // We can add a new index after the entries have been
        // added - this time by name.
        MultiMapIndex<String, Site> byName = multiMap.addIndex((site)->site.name);

        // Get a value by Id.
        System.err.printf("Get by id=7777 = %s\n", byId.get(7777));
        // Get a value by Name
        System.err.printf("Get by name='A Site' = %s\n", byName.get("A Site"));  

        // We can do usual mappy things with the indexes,
        // such as list the keys, or iterate over all entries
        System.err.printf("byId.keys() = %s\n", byId.keySet());
        byId.forEach((Integer id, Site s) -> System.err.printf("   %s => %s\n", id, s));

        // In some cases the map is not unique, so I provide a 
        // way to get all entries with the same value as a list.
        // in this case by their rating value.
        MultiMapIndex<String, List<Site>> byRating = multiMap.addMultiIndex((Site site)->site.rating);
        System.err.printf("byRating('A') = %s\n", byRating.get("A"));
        System.err.printf("byRating('B') = %s\n", byRating.get("B"));

        // Adding stuff after creating the indices is fine.
        multiMap.add(new Site(3333,"Last Site","B"));
        System.err.printf("byRating('A') = %s\n", byRating.get("A"));
        System.err.printf("byRating('B') = %s\n", byRating.get("B"));
    }
}

SOAPFaultException部署在Tomcat上时,但在GlassFish中工作正常 - java

朋友们,我一直在尝试很多,阅读了很多论坛,但无法理解为什么出现此问题。我使用契约优先方法创建了一个Jax-WS WebService。创建WSDL和XSD,然后使用wsimport工具生成其余工件,为SEI提供实现。将WebService应用程序部署到Eclipse Helios中的GlassFish(Glassfish适配器和Eclipse中安装的插件)。…

页面加载而不是提交时发生struts验证 - java

请原谅我;我对Struts有点陌生。我遇到一个问题,即页面加载而不是我实际提交表单时发生了验证。我整天都在论坛上搜寻和搜寻,没有任何运气。我显然做错了一些事情,应该很容易确定,但是我还没有发现问题所在。这是我的struts.xml的片段:<action name="*Test" method="{1}" clas…

DataSourceTransactionManager和JndiObjectFactoryBean和JdbcTemplate的用途是什么? - java

以下的用途是什么:org.springframework.jdbc.core.JdbcTemplate org.springframework.jdbc.datasource.DataSourceTransactionManager org.springframework.jndi.JndiObjectFactoryBean <tx:annotatio…

无法从ArrayList <String>转换为List <Comparable> - java

当我写下面的代码时,编译器说 无法从ArrayList<String>转换为List<Comparable>private List<Comparable> get(){ return new ArrayList<String>(); } 但是当我用通配符编写返回类型时,代码会编译。private List&l…

合并List <T>和List <Optional <T >> - java

鉴于: List<Integer> integers = new ArrayList<>(Arrays.asList( 10, 12 )); List<Optional<Integer>> optionalIntegers = Arrays.asList( Optional.of(5), Optional.em…