Thread View: pl.comp.lang.java
3 messages
3 total messages
Started by Borneq
Fri, 14 Mar 2014 07:05
Co gdy funkcja ma zwrócić dwie rzeczy?
Author: Borneq
Date: Fri, 14 Mar 2014 07:05
Date: Fri, 14 Mar 2014 07:05
6 lines
1146 bytes
1146 bytes
Na przykład TryPop pobierająca ze stosu czy kolejki ma zwrócić: - element - boolean czy udało się zwrócić, czy też struktura jest pusta TryConvert- próbująca konwertować tekst na int czy real W Pascalu obchodzi się to (nie jest to za elegancko) przez parametry będące referencjami czy wskaźnikami i zwracające wartość. A w Javie?
Re: Co gdy funkcja ma zwrócić dwie rzeczy?
Author: Arivald
Date: Fri, 14 Mar 2014 08:14
Date: Fri, 14 Mar 2014 08:14
116 lines
4315 bytes
4315 bytes
On 2014-03-14 08:05, Borneq wrote:
> Na przykład TryPop pobierająca ze stosu czy kolejki ma zwrócić:
> - element
> - boolean czy udało się zwrócić, czy też struktura jest pusta
> TryConvert- próbująca konwertować tekst na int czy real
Najprościej, jeśli element nie może być nullem, zwracaj element, jeśli
null to się nie udało.
> W Pascalu obchodzi się to (nie jest to za elegancko) przez parametry
> będące referencjami czy wskaźnikami i zwracające wartość. A w Javie?
Można zasymulować przekazywanie przez referencję, np. tak:
public class ObjectHolder<T> {
public T o;
public ObjectHolder() {
this.o = null;
}
public ObjectHolder(T o) {
this.o = o;
}
}
i użycie
ObjectHolder<Data> dataRef = new ObjectHolder<Data>();
if (someFunction(param1, param2, dataRef)) {
do something(dataRef.o);
}
Ale to mało eleganckie, używam tylko w testach, kiedy nie chce mi się
pisać specjalnych klas tylko do tego.
W rzeczywistym kodzie, możliwe rozwiązania:
1) Zwracasz Pair<T1, T2>, jeśli jest w bibliotece lub sobie dopisałeś.
Android ma tą klasę. Jest równie prosta, kod na końcu posta.
2) Budujesz osobną, specjalizowaną klasę wyniku, POJO tyko z polami
final, i ją zwracasz z funkcji.
Taką klasę zresztą można przekazywać poprzez parametr, wtefy wynik wyn
kcji możesz użyć do zwrócenia boolean (udało się) lub kodu błędu
(chociaż to lepiej się wyjątkami robi)
3) Budujesz osobną klasę realizującą tą funkcję, z której potem wyniki
pobierasz getterami
Coś jak:
Calculation calc = new Calculation(param1, param2, param 3);
if (calc.getSuccess()) {
something = calc.getResult1();
other= calc.getResult2();
}
Może "Calulation" to nie najlepsza nazwa, ten konstrukt nadaje się do
wywołań RPC / WebService, etc.
4) a jak nie przeszkadza Ci brak silnego typowania, zwróć kolekcję
obiektów, np ArrayList - dostęp po indexie, lub HashMap - dostęp po
kluczu. Ale takie programowanie może prowadzić do trudnych do
debugowania błędów.
Implementacja immutable Pair, którą można używać w HashMapie (ma
hashCode i equals).
public class Pair<A, B> {
public final A first;
public final B second;
public Pair(A first, B second) {
super();
this.first = first;
this.second = second;
}
public static <A, B> Pair <A, B> create(A a, B b) {
return new Pair<A, B>(a, b);
}
public int hashCode() {
int result = 17;
if (first != null) result = 31 * result + first.hashCode();
if (result != null) result = 31 * result + second.hashCode();
return result;
}
public boolean equals(Object other) {
if (other instanceof Pair) {
Pair otherPair = (Pair) other;
return (
(this.first == otherPair.first || (this.first != null &&
otherPair.first != null && this.first.equals(otherPair.first)))
&&
(this.second == otherPair.second ||(this.second != null &&
otherPair.second != null && this.second.equals(otherPair.second)))
);
}
return false;
}
public String toString() {
return "(" + first + ", " + second + ")";
}
}
--
Arivald
Re: Co gdy funkcja ma zwrócić dwie rzeczy?
Author: Piotr Rezmer
Date: Fri, 14 Mar 2014 08:30
Date: Fri, 14 Mar 2014 08:30
23 lines
1870 bytes
1870 bytes
Borneq pisze: > Na przykład TryPop pobierająca ze stosu czy kolejki ma zwrócić: > - element > - boolean czy udało się zwrócić, czy też struktura jest pusta Tutaj można też posilić się generacją wyjątku, np. EStructureEmptyException. Tyle że wtedy zmieniłbym nazwę funkcji z TryPop() na Pop(). A w przypadku gdy będziesz musiał zwrócić więcej obiektów, możesz umieścić ich tyle ile chcesz w pojedynczym obiekcie PopResponse. Podobne podejście stosuje się w szkieletach web services generowanych dla soapEncoding = documentLiteral. Ma to też swoją zaletę że używanie pary FunctionRequest/FunctionResponse upraszcza modyfikację kodów jeśli będziesz chciał dodać jakiś parametr w przyszłości. Tam gdzie go nie potrzebujesz nie będzie potrzeby wprowadzania jakiejkolwiek zmiany (inaczej niż w przypadku function( arg1, arg2, arg3, arg4 ) ) -- pozdrawiam Piotr XLR250&bmw_f650_dakar
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads