2012-06-12 8 views
10

Załóżmy, że mam Map<String, String> i chcę usunąć wszystkie wpisy, których wartość zawiera foo. Jaki jest najlepszy sposób, aby to zrobić, w zakresie optymalizacji/pamięci/itp.? Cztery poniższe syso drukują ten sam wynik, czyli {n2=bar}.Przekaż obiekt jako parametr i zmodyfikuj go w ramach metody

public static void main(String[] args) { 

    Map<String, String> in = new HashMap<String, String>(); 
    in.put("n1", "foo"); 
    in.put("n2", "bar"); 
    in.put("n3", "foobar"); 

    // 1- create a new object with the returned Map 
    Map<String, String> in1 = new HashMap<String, String>(in); 
    Map<String, String> out1 = methodThatReturns(in1); 
    System.out.println(out1); 

    // 2- overwrite the initial Map with the returned one 
    Map<String, String> in2 = new HashMap<String, String>(in); 
    in2 = methodThatReturns(in2); 
    System.out.println(in2); 

    // 3- use the clear/putAll methods 
    Map<String, String> in3 = new HashMap<String, String>(in); 
    methodThatClearsAndReadds(in3); 
    System.out.println(in3); 

    // 4- use an iterator to remove elements 
    Map<String, String> in4 = new HashMap<String, String>(in); 
    methodThatRemoves(in4); 
    System.out.println(in4); 

} 

public static Map<String, String> methodThatReturns(Map<String, String> in) { 
    Map<String, String> out = new HashMap<String, String>(); 
    for(Entry<String, String> entry : in.entrySet()) { 
     if(!entry.getValue().contains("foo")) { 
      out.put(entry.getKey(), entry.getValue()); 
     } 
    } 
    return out; 
} 

public static void methodThatClearsAndReadds(Map<String, String> in) { 
    Map<String, String> out = new HashMap<String, String>(); 
    for(Entry<String, String> entry : in.entrySet()) { 
     if(!entry.getValue().contains("foo")) { 
      out.put(entry.getKey(), entry.getValue()); 
     } 
    } 
    in.clear(); 
    in.putAll(out); 
} 

public static void methodThatRemoves(Map<String, String> in) { 
    for(Iterator<Entry<String, String>> it = in.entrySet().iterator(); it.hasNext();) { 
     if(it.next().getValue().contains("foo")) { 
      it.remove(); 
     } 
    } 
} 

Odpowiedz

4

Najlepszym sposobem jest methodThatRemoves ponieważ:

  1. pod względem zużycia pamięci: nie tworzyć nową mapę, więc nie dodać narzut pamięci.
  2. Pod względem wykorzystania procesora: iterator ma złożoność O (1) do wywoływania następnego lub usuwania bieżącego elementu.
0

bym osobiście pójść z methodThatRemoves bo wykonujesz tylko działanie pętli i sprawdzanie „foo” równości. Inni robią to tak samo, jak tworzenie map obiektów i mapowanie operacji. Więc wyraźnie jedna metoda robi mniej.

Jeśli chcesz zmniejszyć użycie pamięci, lepiej nie tworzyć dodatkowej HashMap tylko po to, aby usunąć 1 lub więcej wpisów. Zakłada to, że nie masz nic przeciwko dodatkowym obliczeniom do iteracji mapy.

Jeśli naprawdę chcesz zajrzeć głębiej, powinieneś ocenić to za pomocą profilera lub jakiegoś rodzaju.

1

Dla mnie najlepszy jest jednym z Iterator - methodThatRemoves, bo nie tworzą pośrednią Mapa i nie używać put metody.

Przy okazji, pierwszy: może być szybszy, ponieważ put złożoność to O (1), podczas gdy w najgorszym przypadku jest to O (n), ale zużyje więcej pamięci, ponieważ masz 2 różne instancje mapy.

2

Najskuteczniejszym sposobem methodThatRemoves, bo

  • Używa prawie nie pamięta
  • nie tworzy obiekty z wyjątkiem (Lightweight) iterator
  • jest bardzo szybki (nie używać żadnych wyszukiwań mapę)

Nie zrobiłbym jednak pierwszej kopii, chyba że posiadasz niezmienną mapę lub musisz zachować oryginał.

+0

nie jest dokładnie to, co robi metodaThatRemoves? – tibtof

+0

tak, jak to się różni od równych sobie, co nie jest tym, czego chce, tak czy inaczej – jonasr

+0

Ups! Pomyślałem sobie:/usunę kod :) – Bohemian

Powiązane problemy