JavaRush /Blog Java /Random-PL /Poziom 26. Odpowiedzi na pytania podczas rozmowy kwalifik...
zor07
Poziom 31
Санкт-Петербург

Poziom 26. Odpowiedzi na pytania podczas rozmowy kwalifikacyjnej na temat poziomu. Część 1. Pytania 1-5, 10.

Opublikowano w grupie Random-PL
Poziom 26. Odpowiedzi na pytania podczas rozmowy kwalifikacyjnej na temat poziomu.  Część 1. Pytania 1-5, 10. - 1Podsumowanie okazało się dość kłopotliwe, dlatego podzieliłem je na dwie części. Część druga zawiera odpowiedzi na pytania dotyczące kankarencji i wielowątkowości. Pierwsza część zawiera resztę. Pisanie było dość trudne. Nadal niewiele rozumiem, więc jak zwykle komentarze, uwagi, uzupełnienia mile widziane)

1. Jak korzystać z interfejsu Comparable?

Interfejs Comparabledeklaruje tylko jedną metodę compareTo(Object obj), przeznaczoną do implementacji porządkowania obiektów klas. Jest wygodny w użyciu podczas sortowania uporządkowanych list lub tablic obiektów. Ta metoda porównuje wywoływany obiekt z obj. W przeciwieństwie do metody equals, która zwraca wartość true lub false , compareTozwraca:
  • 0, jeśli wartości są równe;
  • Wartość ujemna, jeśli wywoływany jest mniejszy niż parametr;
  • Dodatnia, jeśli wywoływany jest większy niż parametr.
Jest przede wszystkim przydatny do sortowania uporządkowanych list ( java.util.List) i tablic obiektów. Jeśli lista/tablica zawiera elementy implementujące ten interfejs, można je automatycznie posortować według java.util.Collections.sort(List)/Arrays.sort(Object[]). Koncepcja porządku naturalnego jest kojarzona z interfejsem Comparable, ponieważ ustanawia naturalny porządek instancji dowolnej klasy, która implementuje ten interfejs. Inaczej mówiąc, rząd (x, y) odpowiada spełnieniu warunku x.compareTo(y) <= 0. Zasady implementacji Comparable, a raczej jej metody, compareTo(Object)są następujące (x i y są instancjami klasy, która implementuje Comparable):
  • x.compareTo(y)zwraca -1 lub 1, jeśli x powinno znajdować się odpowiednio przed lub po y. Jeśli metoda zwróci 0, to rzędy (x, y) i (y, x) są równoważne.
  • Jeśli sign(a)jest funkcją zwracającą -1,0,1 dla odpowiednio mniejszego od 0, równego 0 i większego od 0, to równość musi być spełniona sign(x.compareTo(y))==-sign(y.compareTo(x)). Co jest logiczne: jeśli x występuje przed y, to y musi nastąpić po x i odwrotnie.
  • Jeżeli x.compareTo(y) > 0i y.compareTo(z) > 0, to x.compareTo(z) > 0– relacja przechodniości nierówności.
  • Jeżeli x.compareTo(y) == 0, to sign(x.compare(z)) == sign(y.compareTo(z))dla dowolnego z.
  • Wywołanie x.compareTo(null)musi zgłosić wyjątek NullPointerException. Jest to rozbieżność z logiką implementacji equals(przypomnę, x.equals(null)zwraca false ).
  • Jeśli typu y nie można porównać z x, wówczas wywołanie x.compareTo(y)musi zgłosić wyjątek ClassCastException.
  • (x.compareTo(y) == 0) == x.equals(y), tj. wywołanie x.compareTo(y)musi zwrócić 0 wtedy i tylko wtedy, gdy x.equals(y)zwróci wartość true . Jest to zasada konsekwencji, którą należy wziąć pod uwagę.
Źródła:

2. Jak korzystać z interfejsu Komparatora?

Interfejs Comparatordeklaruje dwie metody compare(Object obj1, Object obj2)i equals(Object obj). Podczas korzystania z interfejsu Comparatorlogika porównywania pary obiektów nie jest ukryta wewnątrz klasy/obiektu, ale jest zaimplementowana w osobnej klasie. Metoda compare(x,y)jest dokładnie taka sama jak wywołanie x.compareTo(y). Wszystkich reguł należy przestrzegać dokładnie w taki sam sposób, jak zasad implementacji metody compareTo(Object)interfejsu Comparable. Comparatormożna zastosować wszędzie tam, gdzie potrzebne jest sortowanie. W tym przypadku po pierwsze pojawia się niezbędna elastyczność - możliwość wdrożenia kilku reguł sortowania. Po drugie, sortowane obiekty mogą nie implementować metody Comparable. Jeśli to wdrożą, Comparatorma to pierwszeństwo. Interfejs Comparatordefiniuje także metodę equals(Object), choć może to paradoksalnie. Ta metoda porównuje same instancje interfejsu Comparatori powinna zwracać wartość true tylko wtedy, gdy porównywane obiekty zapewniają ten sam porządek sortowania. Zawsze jednak można bezpiecznie pozostawić oryginalną implementację Object.equals(Object)w stanie nienaruszonym . Źródło:

3. Jakie metody posiada klasa Collections?

public static <T> boolean addAll(Collection<? super T> c, T... elements) Metoda dodaje elementy tablicy elementsdo kolekcji Collection<? super T> c. Elementy można określać pojedynczo lub jako tablicę. Gdy elementy są określone indywidualnie, metoda ta zapewnia możliwość wygodnego dodania wszystkich elementów do istniejącej kolekcji: Collections.addAll(flavors, "Peaches 'n Plutonium", "Rocky Racoon"); public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c) Obie metody przeszukują listę przekazaną w parametrze dla obiektu przekazanego w parametrze przy użyciu algorytmu wyszukiwania binarnego. Zwraca indeks elementu jeśli taki element istnieje na liście, w przeciwnym wypadku zwraca indeks pierwszego elementu listy większy niż key, jeśli wszystkie elementy są mniejsze niż . Przed użyciem tych metod listy należy posortować. W pierwszym przypadku są one sortowane rosnąco, w „naturalnej” kolejności elementów listy (tak samo jak przy użyciu ). W drugim przypadku lista musi być posortowana rosnąco w kolejności podanej przez przekazany komparator (taka sama kolejność jak przy użyciu [tutaj "z" to komparator z parametrów opisywanej metody]) Preambuła: mechanizm generyczny w języku zapewnia sprawdzanie typu w czasie kompilacji. Zwykle to wystarczy, ale zdarzają się przypadki, gdy tak nie jest. Przykładowo przenosimy naszą kolekcję do kodu biblioteki, gdzieś nam nieznanego i bardzo zależy nam na tym, aby kod tej „obcej biblioteki” nie wstawiał do naszej kolekcji elementu niewłaściwego typu. Jest to możliwy problem nr 1. Możliwy problem nr 2 jest następujący. Załóżmy, że nasz program wysyła nam komunikat informujący, że do kolekcji wstawiono element niewłaściwego typu. Niestety, ten wyjątek może zostać zgłoszony w dowolnym momencie po wstawieniu nieprawidłowego elementu i zwykle daje nam niewiele lub wcale informacji o źródle problemu. Stosując metodę metodyczną możemy uchronić się od problemów pierwszego i drugiego, ponieważ ta metoda tworzy kolekcję, którą można zweryfikować w czasie wykonywania. Rozwiązywanie problemu numer dwa za pomocą tej metody: Na przykład mamy coś takiego i wypada . key list.size() Collections.sort(list) Collections.sort(list, c) public static <E> Collection<E> checkedCollection(Collection<E> c, Class<E> type) ClassCastException checkedCollection ClassCastException
Collection<String> c = new HashSet<String>();
Powyższy kod można tymczasowo zastąpić:
Collection<String> c = Collections.checkedCollection(
         new HashSet<String>(), String.class);
Kiedy ponownie uruchomimy program, lokalizujemy linię kodu, która wstawia do naszej kolekcji element niewłaściwego typu. Moim zdaniem pokrewne metody: public static <E> List<E> checkedList(List<E> list,Class<E> type) public static <K,V> Map<K,V> checkedMap(Map<K,V> m, Class<K> keyType,Class<V> valueType) public static <E> Set<E> checkedSet(Set<E> s,Class<E> type) public static <K,V> SortedMap<K,V> checkedSortedMap(SortedMap<K,V> m,Class<K> keyType,Class<V> valueType) public static <E> SortedSet<E> checkedSortedSet(SortedSet<E> s,Class<E> type) public static <T> void copy(List<? super T> dest,List<? extends T> src) Metoda kopiuje elementy src do dest. indeksy skopiowanych elementów będą takie same. public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) public static <T> T min(Collection<? extends T> coll,Comparator<? super T> comp) public static <T> T max(Collection<? extends T> coll,Comparator<? super T> comp) metody zwracają element minimalny/maksymalny w kolekcji w kategoriach „porządku naturalnego” (interfejs Comparable) lub kolejności przekazanego komparatora. public static boolean disjoint(Collection<?> c1,Collection<?> c2) Zwraca wartość true , jeśli kolekcje nie zawierają identycznych elementów. <T> List <T> emptyList(), <K,V> Map <K,V> emptyMap(), <T> Set <T> emptySet()– zwróć odpowiednio pustą listę, mapę i zestaw; <T> void fill(List<? super T> list, T obj)– wypełnia listę podanym elementem; int frequency(Collection<?> c, Object o)– zwraca liczbę wystąpień danego elementu w kolekcji; <T> List <T> nCopies(int n, T o)– zwraca listę n określonych elementów; <T> boolean replaceAll(List<T> list, T oldVal, T newVal)– zastępuje wszystkie określone elementy nowymi; void reverse(List<?> list)– „odwraca” listę; void rotate(List<?> list, int distance)– przesuwa listę cyklicznie o określoną liczbę elementów; void shuffle(List<?> list)– tasuje elementy listy; <T> Set <T> singleton(T o), singletonList(T o), singletonMap(K key, V value)– stworzyć zestaw, zestawienie i mapę wystawową składającą się z jednego elementu; <T extends Comparable<? super T>> void sort(List<T> list), <T> void sort(List<T> list, Comparator<? super T> c)– sortowanie listy w naturalnej kolejności i Comparatorodpowiednie jej wykorzystanie; void swap(List<?> list, int i, int j)– zamienia elementy listy na określonych pozycjach. Źródła:

4. Jakie metody posiada klasa Arrays?

Pełną listę metod klasy Arrays można zobaczyć w dokumentacji . W tym podsumowaniu przytoczę tylko kilka z nich. [przetłumaczyłem metody z dokumentacji i niestety straciłem większość mojego tłumaczenia. Szkoda, a nie chcę tracić czasu na to samo, więc wkleję to, co wygooglowałem] public static <T> List<T> asList(T... a) generuje listę na podstawie tablicy. Tablica służy do wewnętrznej reprezentacji listy. Zachowuje to połączenie między listą a oryginalną tablicą: zmiany w tablicy zostaną odzwierciedlone na liście:
String[] a = { "foo", "bar", "baz"};
List<String> list = Arrays.asList(a);
System.out.println(list); // [foo, bar, baz]

a[0] = "aaa";
System.out.println(list); // [aaa, bar, baz]
zmiany na liście zostaną odzwierciedlone w tablicy:
String[] a = { "foo", "bar", "baz"};
List<String> list = Arrays.asList(a);
System.out.println(list); // [foo, bar, baz]

list.set(0, "bbb");
System.out.println(Arrays.toString(a)); // [bbb, bar, baz]
Jeśli tablica zawiera obiekty, oczywiście zarówno tablica, jak i lista będą odnosić się do tych samych instancji:
Object[] a = { new Object(), new Object(), new Object()};
List<Object> list = Arrays.asList(a);
System.out.println(a[0] == list.get(0)); // true
int binarySearch(параметры)– przeciążona metoda organizacji wyszukiwania binarnego wartości w tablicach typów pierwotnych i obiektowych. Zwraca pozycję pierwszego dopasowania; void fill(параметры)– przeciążona metoda wypełniania tablic wartościami różnych typów i prymitywami; void sort(parameters) – przeciążona metoda sortowania tablicy lub jej części przy użyciu interfejsu Comparator i bez niego; static <T> T[] copyOf(T[] original, int newLength)– wypełnia tablicę o określonej długości, odrzucając elementy lub wypełniając null, jeśli to konieczne; static <T> T[] copyOfRange(T[] original, int from, int to)– kopiuje określony obszar tablicy do nowej tablicy; <T> List<T> asList(T… a)– metoda kopiująca elementy tablicy do obiektu typu List<T>. Źródło:

5. Jaka jest nazwa sortowania używanego podczas wywoływania Collections.sort()?

Z dokumentacji : Implementacja jest adaptacją sortowania list Tima Petersa w Pythonie (TimSort). Ta implementacja zrzuca listę do tablicy, sortuje ją, następnie wykonuje iterację po liście i ponownie ładuje każdy element listy z odpowiedniego elementu tablicy. Pozwala to uniknąć złożoności n*n log(n), która mogłaby powstać przy próbie bezpośredniego sortowania połączonej listy. Z wiki : Timsort to hybrydowy algorytm sortowania łączący sortowanie przez wstawianie i sortowanie przez scalanie, opublikowany w 2002 roku przez Tima Petersa. Timsort jest obecnie standardowym algorytmem sortowania w Pythonie, OpenJDK 7 i zaimplementowanym w Androidzie JDK 1.5. Główną ideą algorytmu jest to, że w świecie rzeczywistym sortowalne tablice danych często zawierają uporządkowane podtablice. Na takich danych Timsort działa znacznie szybciej niż wiele algorytmów sortujących.

10. Co to jest iterator?

Interfejs wprowadzony w wersji JDK 1.2 języka Java java.util.Iteratorpozwala na iterację klas kontenerów. Każdy Iterator implementuje metody next()i hasNext()opcjonalnie może obsługiwać remove(). Iteratory są tworzone przez odpowiednie klasy kontenerów, zwykle przez klasę iterator(). Metoda next()przesuwa iterator do następnej wartości i zwraca określoną wartość do iteratora. Po utworzeniu iterator wskazuje specjalną wartość przed pierwszym elementem, więc pierwszy element można pobrać dopiero po pierwszym wywołaniu next(). Aby określić moment, w którym wszystkie elementy w kontenerze zostały poddane iteracji, stosuje się metodę testową hasNext(). Poniższy przykład ilustruje proste użycie iteratorów:
Iterator iter = list.iterator();
//Iterator<MyType> iter = list.iterator(); в J2SE 5.0
while (iter.hasNext())
    System.out.println(iter.next());
W przypadku kolekcji typów, która to obsługuje, metoda iteratora remove()usuwa ostatni „odwiedzony” element z kontenera. Prawie wszystkie inne typy modyfikacji kontenera podczas iteracji są niebezpieczne. Dodatkowo for java.util.Lististnieje java.util.ListIteratorz podobnym API, ale umożliwia iterację do przodu i do tyłu, podając definicję bieżącego indeksu na liście i przenosząc się do elementu po jego pozycji. Źródło: Część 2
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION