2015-08-24 58 views
1

這是更快:速度定製的Java類與地圖

  1. 一個Set,其元素各自定義如下的CustomObject一個實例:

    public class CustomObject{ 
    
        private static String A; 
        private static String B; 
        private static String C; 
    
        public static String getA(){ 
         return A; 
        } 
    
        public static getB(){ 
         return B; 
        } 
    
        public static getC(){ 
         return C; 
        } 
    } 
    
  2. 一個Set,其元素是每個的Map<String, String>這樣的情況:每個地圖的格式是{"A" : Avalue, "B" : Bvalue, "C" : Cvalue}的?

  3. ,或者你能想到更好的捕捉這個數據的任何其他數據結構

,如果我想獲得的所有對象/圖誰擁有屬性/鍵A ==「someValue中的一個子集「?

您可以使用.filter,或任何其他圖書館。另外,如果答案很大,答案會改變嗎?

編輯:我剛剛讓我的一位同事告訴我,自定義類的運行時比散列圖快 - 爲什麼有人會使用散列表呢?

+3

更好的運行時間......什麼?對不起,我不清楚你的意思。 –

+1

_you_想什麼?這似乎是功課,所以這個問題應該顯示一些研究工作。 –

+0

你是什麼意思,「A」==「a」? (一般來說,如果你知道所有你需要的變量,自定義類將會變得更好。) –

回答

1

我假設我們1〜2個數量級

public class CustomObject { 
    private String a, b, c; 

    public CustomObject(String a, String b, String c) { 
     this.a = a; this.b = b; this.c = c; 
    } 
    public String getA() { return a; } 
    public String getB() { return b; } 
    public String getC() { return c; } 
} 

如果我們比較的操作是obj.getA()map.get("A"),然後將自定義地圖會更快,大概是:在比較Map<String, String>等效自定義類型是這樣的。是的...快得多。

在另一方面,如果我們把CustomObject情況下爲一組「混合型」的對象,他的田地,我們不知道任何有關的然後調用getA變得更加困難/昂貴,而且Map解決方案肯定更簡單,可能也更快。 (這取決於你可以做出的假設。)


此外,沒有答案的變化如果設定爲大?

不,它不會顯着改變性能特徵。


使用-情況下,最好是使用Map是當設定可能的密鑰在編譯時不知道。這意味着您不能將CustomClass作爲手寫源代碼的常規類書寫。

實際上,在大多數情況下,這兩種方法的相對代碼簡單性和健壯性應該決定您採取的方法。如果密鑰是靜態的,則obj.getA()方法不僅僅更快。它也更加強大,因爲你不會意外地寫出類似map.get("a")而不是map.get("A") ......這將返回一個意外的null並可能導致NPE。如果密鑰在編譯時是動態的/未知的,則map.get("A")更簡單並且可能更健壯。

0

如果您在多次尋找其尋找最優的運行時性能將含有特定的屬性值,那麼您可能需要使用數據庫(或內存中的一個)或手動非標準化數據,這樣你保持爲每個屬性列表的圖,由其值鍵控。 請注意,此解決方案是唯一值得的,如果這些查找足夠頻繁,表現足以關鍵,以保證數據的重複成本。

E.g.

// aSets is a map to a list of all the sets which have 
// a specified value for field "_A" (values being the map key) 
Map<String, List<Set<MyObject>>> aSets; 
Map<String, List<Set<MyObject>>> bSets; 
... 

這並不理想,但它提供了所需的查找。

編寫一個索引器類並不難,因爲它使用對所提供集合的基礎對象的反射自動創建這些映射。我寫了一些代碼,做這樣的事情前一段時間作爲一個概念的東西或其他證明。從未使用過它,但保留了它身邊......這是註釋掉和使用您自己的風險(和它不會對集合書面工作,但會很容易地修改):

public class Indexer 
{ 
    private Map<String,Map<Object,Set<Object>>> index = new HashMap<String,Map<Object,Set<Object>>>(); 

    public void add(Object object) throws Exception 
    { 
     BeanInfo info = Introspector.getBeanInfo(object.getClass()); 

     PropertyDescriptor[] propertyDescriptors = info.getPropertyDescriptors(); 
     for (PropertyDescriptor descriptor : propertyDescriptors) 
     { 
      String fieldName = descriptor.getName(); 
      Map<Object,Set<Object>> map = index.get(fieldName); 
      if (map == null) 
      { 
       map = new HashMap<Object,Set<Object>>(); 
       index.put(fieldName, map); 
      } 
      Method method = descriptor.getReadMethod(); 
      Object data = method.invoke(object); 
      Set<Object> set = map.get(data); 
      if (set == null) 
      { 
       set = new HashSet<Object>(); 
       map.put(data, set); 
      } 
      set.add(object); 
     } 

    } 

    public Set<Object> get(String fieldName, Object value) 
    { 
     Map<Object,Set<Object>> map = index.get(fieldName); 
     if (map != null) 
     { 
      Set<Object> set = map.get(value); 
      if (set != null) 
      { 
       return Collections.unmodifiableSet(set); 
      } 
     } 

     return null; 
    } 


    public static class Test 
    { 
     private String value1; 
     private String value2; 
     public int number; 

     public Test(String v1, String v2, int n) 
     { 
      value1 = v1; 
      value2 = v2; 
      number = n; 
     } 

     public String getValue1() 
     { 
      return value1; 
     } 

     public void setValue1(String value1) 
     { 
      this.value1 = value1; 
     } 

     public String getValue2() 
     { 
      return value2; 
     } 

     public void setValue2(String value2) 
     { 
      this.value2 = value2; 
     } 


     @Override 
     public String toString() 
     { 
      return "Test [value1=" + value1 + ", value2=" + value2 + ", number=" + number + "]"; 
     } 


    } 

    public static void main(String[] args) throws Exception 
    { 
     Test test1 = new Test("blue", "dog", 5); 
     Test test2 = new Test("blue", "cat", 10); 
     Test test3 = new Test("green", "duck", 10); 

     Indexer indexer = new Indexer(); 
     indexer.add(test1); 
     indexer.add(test2); 
     indexer.add(test3); 

     System.out.println("get value1 = blue: \n" + indexer.get("value1", "blue")); 
     System.out.println("\nget value1 = green: \n" + indexer.get("value1", "green")); 
     System.out.println("\nget number = 5: \n" + indexer.get("number", 5)); 
     System.out.println("\nget number = 10: \n" + indexer.get("number", 10)); 

    } 

} 
0

Java類更快。

我剛剛有一位同事告訴我,自定義類的運行時比散列表快,爲什麼有人會使用散列表呢?

因爲您可能有興趣存儲動態生成的值和/或事先不知道您的類將具有的屬性。