2009-04-28 2 views
4

환경 설정이있는 사용자를 위해 Java에서 HashMap을 만들고 싶습니다. 이것은 데이터베이스에서 쉽게 할 수 있지만 불행히도 데이터베이스를 사용할 수는 없습니다. 필요한 것은 HashMap에서 이름으로 사용자를 찾고 특정 관심사 (예 : 골프)를 가진 모든 사용자를 찾는 것입니다. 사용자를 삭제하면 모든 관심사를 삭제해야합니다.2 개의 키로 색인 된 Java HashMap

누구나이 데이터 구조를 만드는 좋은 방법을 알고 있습니까?

+0

일부 답변에서 볼 수 있듯이 귀하의 피사체가 오도 된 것 같습니다. – starblue

답변

9

정말 두 번째 색인이 필요하다는 것을 알고 계십니까? 수백만 명의 사용자가없는 한 모든 사용자에 대한 검색이 빠름을 알 수 있습니다.

다음 예는 1,000 명의 사용자를 검색하는 데 51 마이크로 초가 걸립니다. 10,000 명의 사용자를 검사하는 데 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 
    } 
} 
15

정보를 보유하기위한 자체 데이터 구조를 만들 것을 제안합니다. 이 클래스 안에는 관련 정보를 저장하는 두 개의 HashMap이있을 수 있습니다. 그런 다음 사용자 삽입 및 삭제 방법을 직접 작성하십시오.

이 방법을 사용하면 각 속성을 개별적으로 쿼리 할 수있는 반면 삽입/삭제 작업을 제어 할 수 있습니다.

3

내가 키와 값이 userpreferences을 includs 모든 개체 수와 사용자가 다음을 포함

의 HashMap를 구현하는 것이이 스레드를 확인합니다. 사용자 환경 설정에는 예를 들어 관심 목록이 포함됩니다.

관심 분야 및 관심있는 사용자 목록이있는 추가 HashMap.

사용자를 삭제하면 관심있는 모든 것을 가져 와서 관심있는 HashMap 목록에서 사용자 이름을 삭제할 수 있습니다. 관심 HashMap 목록이 비어 있으면 HashMap에서 관심사를 삭제할 수 있습니다.

2 명 이상의 사용자가 동일한 관심을 가질 때주의하십시오. 한 명의 사용자 만 삭제하면 관심을 삭제할 수 없습니다.

단점은 중복 정보가 있다는 것입니다.

4

사용자를 ArrayList에 넣고 필요한 항목을 찾을 때까지 계속 걸어갑니다. 각 사용자에게 일련의 관심사를 부여하십시오. 너무 오래 걸리는 사용자를 확보 한 후에는 정렬하십시오.

시간이 오래 걸리면 관심 분야 분포를 살펴보십시오. 다른 수가 적 으면 비트 맵에 저장하십시오. 한정된 이해 관계의 조합이있는 경우 별도로 저장하고 사용자에게 제공하십시오.

컴퓨터를 빨리 시작하십시오. 하지만 구현을 숨기면 변경할 수 있습니다.

[음, 부정 표를 얻습니다.] 이 코드가 데이터베이스만큼 느리기 전에 많은 사용자가 필요합니다. (현재 하드웨어에서 최소 수십만 개)

4

이것은 사용자의 요구에 과도 할 수 있습니다. 그러나 사용자의 요구가 얼마나 복잡하고 속도가 민감한 지 알지 못하므로 밖으로 던질 것입니다.

데이터를 처리 할 수있는 메모리 내장 (또는 SQLite 기반의 로컬 디스크) 데이터베이스를 고려해 보셨습니까? 그렇게하면 자신의 코드를 작성하는 데 드는 비용을 들이지 않고도 데이터를 검색/색인하는 방법에 훨씬 더 많은 힘을 실어 줄 수있는 방식으로 데이터를 저장할 수 있습니다.

2

2 개의 HashMaps를 사용할 수 있습니다. 그러나 물마루 환경 설정 만 찾는 것은 복잡 할 수 있습니다.

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); 

어쩌면이 솔루션이 더 이상 필요하지 않을 수도 있지만 많은 사람들이 여전히 동일한 문제가 있습니다.