lista typu klasy

0

Klasa Person zawiera pola: imie, nazwisko, wiek. Wszystkie pola sa prywatne.
List<Person> people = new ArrayList<Person>();

Chciałbym napisać funkcję poza klasą , która będzie "coś" robiła , może dla przykładu obliczała sumę wieku osób z tej listy - albo inaczej - listy o typie Person. Czemu tak? Po prostu chciałbym, by stworzyć klasę, która "uporządkuje" dane, a nie będzie zawalała kodu , który zawiera deklarację klasy. Wiem, że mogę to zrobić w klasie i samo działanie programu się dużo nie zmieni, ale na przykład w przypadku gdyby w klasie zawarte było kilkadziesiąt pól , albo mielibyśmy kilkanaście list i dla każdej coś policzyć to już czytelność kodu strasznie by ucierpiała. Fajnie byłoby mieć funkcję , która przyjmowała by parametr , który juz nawet podamy w mainie a nie za każdym razem pisać :

for(Person p: lista2) 
{
   Coś tam...
}

for(Person p: lista3) 
{
    Coś tam...
}

for(Person p: lista4) 
{
    Coś tam...
}

itd.
Chciałbym jako parametr wejściowy tej funkcji podać właśnie listę typu Person. Udało mi się to zrobić w klasie, w której zadeklarowałem Listę, ale niestety nie wiem jak "nazkazać" fukcji by przyjęła właśnie jako parametr listę typu Person... Sory za tą wiązankę, ale nie potrafiłem jakos tego ująć w paru słowach. Z góry dzięki za pomoc.

0

Jeśli chodzi o umiejscowienie metod, które nie muszą być w Twojej klasie to możesz zrobić do tego osobną klasę, publiczną o nazwie np. PersonUtility i w niej zamieścić statyczne funkcje, które operowałyby na liście z obiektami Person. Takie samo rozwiązanie ma framework Collections (To właśnie ten z listami, mapami, kolejkami itp) - np. możesz posortować kolekcję obiektów, która implementuje interfejs Comparable za pomocą statycznej metody sort klasy Collections.

A więc , żeby zaimplementować takie rozwiązanie, tworzysz nową, publiczną klasę. Metody, które przyjmują listę typu Person muszą używać typów generycznych, tych samych, których używa interfejs List<T> i klasa ArrayList (Poczytaj jeśli nie wiesz co to są typu generyczne)

Sygnatura takiej metody, jak napisałeś - np. do dodania wieku wszystkich osób z listy, będzie wyglądać tak:

public static int sumAge(List<? extends Person> list) {...}

Dzięki temu jako argument, do metody będziesz mógł przekazać listę obiektów Person lub listę obiektów podklas klasy Person (Np. jeśli w przyszłosci będziesz chciał rozszerzyć klasę Person, np. stworzyć podklasy Friend, FamilyMember, Employee, itp. to będziesz mógł zsumować wiek za pomocą tej samej metody przekazując listę z nowymi obiektami podklas Friend, FamilyMember, Employee, itp.

0

Dzięki Ci wielkie, o typach generycznych na pewno doczytam , pozdrowionka.

2

@polgol
Takie coś już istnieje, i nazywa się Stream.

Np.

int sumOfAges = personList.stream().mapToInt(p -> p.getAge()).sum();

Ewentualnie można to oczywiście zrobić na lambdach (jeśli zamierzasz używać tego wiele razy):

IntFunction<Collection<? extends Person>> summator = (c -> c.stream().mapToInt(p -> getAge()).sum();
int sum1 = summator.apply(lista1);
int sum2 = summator.apply(lista2); 
// itp.

Generalnie - na pewno warto douczyć się o typach generycznych, ale warto też nauczyć się stream'ów i lambd.

0

Co do list, to mam nadzieję - ostanie pytanie w tym temacie. W jaki sposób mogę porównać rozmiar list? Na przykład chcę spawdzić w której liście jest najwięcej elementów. Listy zgodne z powyższym:

List<person> people1 = new ArrayList<person>();
List<person> people2 = new ArrayList<person>();
List<person> people3 = new ArrayList<person>();
List<person> people4 = new ArrayList<person>();

Dzięki :)

0

Obiekty Collection, w tym i List, zawierają metodę size() - zwraca ona liczbę elementów. Po prostu wybierz tę z największym.

Np.

Stream.of(list1, list2, list3, list4).sorted((l1, l2) -> Integer.compare(l1.size(), l2.size())).findFirst().get();
0

Jeżeli nie wiesz z góry ile list people,people2,.. będziesz tworzył (albo wiesz, ale będzie ich dużo), to warto utworzyć kolekcję list.

1 użytkowników online, w tym zalogowanych: 0, gości: 1