2013-03-04 9 views
5

wydaje mi się stworzyć te dwa rodzaje metod okazyjnie:Zbieranie błędy w metodzie Java, pusty ArrayList kontra LinkedList

// return null on errors, and append errors to 2nd param, otherwise return result 
String fetchSomething(String parameter, List<String> errorMessagesOut); 

// return empty list or null on no errors, otherwise list of errors 
List<String> verifySomething(String parameter); 

a następnie kod, który wywołuje te dołączy do listy błędzie z odpowiednim separatorem (taki jako prosty przecinek, znak nowej linii, znaczniki HTML ...), zwykle z użyciem metody Apache Commons Stringutils.join. A w normalnym przypadku nie ma błędu, a lista będzie pusta.

Więc zacząłem zastanawiać tych dwóch pytań:

  1. Czy widzisz problem z powrotem sznurki komunikat o błędzie, jak liście? Jeśli tak, jaka jest lepsza alternatywa? (nie wyjątki, które będą rzucane przez kod, który wywołuje te metody, kiedy jest to potrzebne.)

  2. Czy new LinkedList() lub new ArrayList(0) lub new ArrayList() lepiej na liście, która jest spodziewać pozostać puste, a które normalnie powinny mieć tylko dostęp sekwencyjny do iteratora, gdy nie jest pusty?


EDIT: Przykład przypadek użycia:

List<String> verifyParameters(JSONObject params) { 
    List<String> ret = new ArrayList<String>(0); 

    if (!verifyKey(params.get("key"))) 
     ret.add("Invalid key: " + key); 

    if (!verifyAccess(params.get("user"), params.get("pass"))) 
     ret.add("Authentication error"); 

    return ret; 
} 

...

List<String> errors = verifyParameters(params); 
if (!errors.isEmpty()) { 

    connection.sendErrorListMessage(errors); 
    logger.warn(StringUtils.join(errors, ", ")); 
    controlPanel.show("Errors: \n- " + StringUtils.join(errors, "\n- ") + '\n'); 
    throw new AbortException("invalid params); // or maybe return false/null; 
} 
// proceed with valid params 

Zazwyczaj manipulacyjny liście błędów nie mieć tych wszystkich, to po prostu stara się zilustrować punkt, w którym lista błędów jest listą komunikatów przeznaczonych dla ludzi, niezależnie od tego, jak zostaną pokazane, a także niezwiązanych z/użytecznych do obsługi d inne błędy w inny sposób.

+3

Zachowaj prosty, użyj 'new ArrayList()'. Jeśli później pojawią się problemy, zmień je na 'nowa ArrayList (0)' lub nawet na 'new LinkedList()'. Mikro-optymalizacja jest źródłem wszelkiego zła –

+0

@LuiggiMendoza - podoba mi się, że był w stanie użyć tego cytatu dwa razy w ciągu pięciu minut :) nice – cowls

+0

LinkedList oczywiście, jako dopasowanie struktury danych. Zwracanie listy zamiast pozwalania na wypełnienie parametru jest bardziej czytelne. –

Odpowiedz

3

Myślę, że dobrze jest używać listy dla ciągów.Byłbym skłonny do dedykowanego Result klasę przynajmniej fetchSomthing i zrobić to w ten sposób, zwłaszcza jeśli errorMessagesOut przeszedł nigdy nie ma niczego oprócz nowej pustej listy:

Result result = fetchSomething(String parameter); 
if (result.hasErrors()) { 
    List<String> errors = result.getErrors(); 
} else { 
    String fetched = result.getValue(); 
} 

bym wtedy też umieścić dowolną z metod że proces strun błąd na tej klasy także więc można zrobić coś takiego:

String errorMessage = result.getErrorString(); 

Ten obudowuje dane o błędach i formatowanie go w jednej klasie i oznacza, że ​​w przypadku braku błędów nie robić trzeba utworzyć dowolną listę wewnętrznie w instancji wyników.

Moje powyższe punkty dotyczą głównie projektu kodu. Nie ma sensu próbować mikrooptymalizacji bez profilowania i mieć benchmarki do porównania z wynikami wszelkich zmian.

1

Do czego służą te błędy? Czy zamierzasz podjąć decyzję biznesową nad błędami zwróconymi przez metodę? W przeciwnym razie, jeśli błędy służą tylko do logowania, proste rozwiązanie do rejestrowania sugeruje, że błędy są rejestrowane natychmiast po ich wystąpieniu. Mówię o tych logger.debug("Error message");.

W każdym razie, czy możesz podać nam przykład tego, co zostało zrobione tym błędom po ich zwróceniu?

Jedną z rzeczy, o której mówię: To może być mylące, jeśli używasz tej samej tablicy/listy/kolekcji zarówno dla wyników przetwarzania, jak i błędów. Byłoby również mylące, gdyby twoje metody zwróciły listy błędów (lub puste/puste listy w przypadku braku błędu), ponieważ wydaje się, że błędy są właśnie wynikiem wykonania twojej metody.

+0

Dodałem uproszczony przykład użycia. W każdym razie, zamiarem jest, aby uzyskać * wszystkie * błędy, a nie po prostu zrezygnować z pierwszego. – hyde

1

Nie ma nic złego w próbie zebrania wszystkich informacji o błędach za pomocą listy. Praca z będzie działać dobrze, nie musisz się o to martwić ...

Jeśli wiesz, że nie ma błędów, możesz return Collections.emptyList();.

Ogólnie w kolekcjach unikaj zwracania zarówno null lub pustej listy. Zawsze używam pustej listy, ponieważ nie łamie się dla pętli.

1

Czy widzisz problem z zwracaniem ciągów komunikatów o błędach jako listy? Jeśli , co jest lepszą alternatywą?

Nie. Nie ma nic złego w korzystaniu z listy, jeśli rozwiązuje ona problem.

Czy new LinkedList() lub new ArrayList(0) lub new ArrayList() lepiej listy, która powinna pozostać pusta, a które normalnie powinny mieć tylko sekwencyjny dostęp iteracyjnej, gdy nie jest pusty?

Wiedząc o ile elementy lista będzie przechowywać i uruchamianiu listę z tym charakterze nie będzie miał żadnego znaczącą poprawę wydajności:

Każda instancja ArrayList ma pojemność. Pojemność jest równa tablicy używanej do przechowywania elementów na liście. Zawsze jest na poziomie co najmniej tak duży, jak rozmiar listy. Gdy elementy są dodawane do tablicy ArrayList , jej pojemność rośnie automatycznie. Szczegóły polityki wzrostu nie są określone poza faktem, że dodanie elementu ma stały zamortyzowany koszt czasu.

Będziesz jednak zaoszczędzić trochę pamięci z new ArrayList(0) jeśli lista jest pusta najczęściej jako wielkość listy jest inicjowany 10 gdy nie jest określona początkowa pojemność.