代码之家  ›  专栏  ›  技术社区  ›  Marius

Java HashMap在2个键上建立索引

  •  4
  • Marius  · 技术社区  · 17 年前

    有人知道一种制作这种数据结构的好方法吗?

    8 回复  |  直到 17 年前
        1
  •  15
  •   B.E.    17 年前

    我建议您创建自己的数据结构来保存信息。在该类中,可以有两个存储相关信息的哈希映射。然后编写自己的方法来插入和删除用户。

    这样,您可以控制插入/删除操作,同时可以单独查询每个属性。

        2
  •  9
  •   Peter Lawrey    17 年前

    下面的示例需要51微秒来扫描1000个用户。扫描10000个用户需要557微秒。

    import java.util.*;
    import java.io.*;
    
    public class TestExecutor {
        public static void main(String[] args) throws IOException {
            Map<String, User> users = new LinkedHashMap<String, User>();
            generateUsers(users, 1000, 0.1);
    
            // warmup.
            int count = 10000;
            for(int i=0;i< count;i++)
                getAllUsersWithInterest(users, Interest.Golf);
    
            long start = System.nanoTime();
            for(int i=0;i< count;i++)
                getAllUsersWithInterest(users, Interest.Golf);
            long time = System.nanoTime() - start;
            System.out.printf("Average search time %,d micro-seconds%n", time/ count/1000);
        }
    
        private static Set<User> getAllUsersWithInterest(Map<String, User> users, Interest golf) {
            Set<User> ret = new LinkedHashSet<User>();
            for (User user : users.values()) {
                if (user.interests.contains(golf))
                    ret.add(user);
            }
            return ret;
        }
    
        private static void generateUsers(Map<String, User> users, int count, double interestedInGolf) {
            Random rand = new Random();
            while(users.size() < count) {
                String name = Long.toString(rand.nextLong(), 36);
                EnumSet<Interest> interests = rand.nextFloat() < interestedInGolf
                        ? EnumSet.of(Interest.Golf) : EnumSet.noneOf(Interest.class);
                users.put(name, new User(name, interests));
            }
        }
    
        static class User {
            private final String name;
            private final Set<Interest> interests;
    
            User(String name, Set<Interest> interests) {
                this.name = name;
                this.interests = interests;
            }
        }
    
        enum Interest {
            Golf
        }
    }
    
        3
  •  6
  •   Community Mohan Dere    9 年前

    最简单的解决方案是使用Commons集合 MultiKeyMap

    …也检查这个线程 genericized-commons-collection

        4
  •  5
  •   Chii    17 年前

    看起来您可以使用双向地图之类的东西来实现类似的功能。退房 http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/collect/BiMap.html

        5
  •  4
  •   RHSeeger    17 年前

    这对于你的需求来说可能有些过分,但我不知道你的需求有多复杂,对速度有多敏感,所以我会把它扔出去。。。

    您是否考虑过使用内存(甚至基于本地磁盘,如SQLite)数据库来处理您的数据。这样做将允许您以一种方式存储数据,从而在搜索/索引数据时获得更大的能力,而无需编写自己的代码。

        6
  •  4
  •   Stephan Eggermont    16 年前

    只需将用户放在ArrayList中,仔细查看,直到找到所需的用户。给每个用户一组兴趣。一旦你得到了足够多的用户,这需要很长的时间,对他们进行排序。

    一旦时间太长,就看看利益分配。如果不同的文件数量较少,请将它们存储在位图中。如果您有一组有限的兴趣组合,请分别存储它们并为用户提供其中之一。

    [嗯,这件事投了反对票]。看看这个问题:在这段代码像数据库一样慢之前,您需要大量的用户。(在当前硬件上,至少有几十万)

        7
  •  3
  •   Markus Lausberg    17 年前

    当您删除一个用户时,您可以获得他所有的兴趣,并从兴趣HashMap列表中删除用户名。 当兴趣HashMap列表为空时,可以从HashMap中删除兴趣。

    当两个或更多用户有相同兴趣时,请小心。只有一个用户被删除时,您不能删除兴趣。

    缺点是,你会有多余的信息。

        8
  •  2
  •   Konstantin Petrukhnov    17 年前

    您可以使用2个哈希映射。但只搜索槽偏好可能会很复杂。

    HashMap <String,Hashmap> users;
    
    //save data
    //create new user
    HashMap <String,String> prefs;
    //save prefs
    prefs.put(pref1,value1);
    prefs.put(pref2,value2);
    //save user
    users.put(user1,prefs);
    
    //get data
    String x = users.get(user1).get(pref1);