• ,

Уровень 8: план уровня и доп. материалы

План уровня:
  • Коллекции: LinkedList, HashSet, HashMap. Date — дата.
  • Коллекции Set — множество, List — список, Map — словарь (или карта).
  • List -> ArrayList, LinkedList, Vector, Stack.
  • Set -> HashSet, TreeSet, SortedSet.
  • Map -> HashMap, TreeMap, SortedMap, Hashtable.
  • Отличие реализаций
  • Работа с итераторами Iterator. Методы hasNext(), next()
  • Map.Entry. Методы getKey(), getValue()
  • Работа с датой — класс Date.

  • На этом уровне изучается обзор коллекций. Детальное углубленное изучение будет на 30+ уровнях.

    Курс Java

Что еще можно посмотреть на досуге:
Почитать про коллекции
Статья на хабре про ArrayList
Статья на хабре про LinkedList

habrahabr.ru/post/128017/

Пример удаления записей из мапы:

Map<String, String> map = new HashMap<>();
map.put("1", "2");
map.put("3", "4");

Map<String, String> mapCopy = new HashMap<>(map);
for(Map.Entry<String, String> pair : mapCopy.entrySet()) {
    map.remove(pair.getKey());
}



Нашли классную ссылку к материалу данной темы? Добавьте ее сюда в виде комментария.
Возможно, именно Ваша ссылка поможет другому человеку стать программистом и улучшить свою жизнь!

Вернуться к плану обучения

Вернуться к обучению java онлайн на JavaRush

74 комментария

Walmar
Скажите, пожалуйста, зачем при создании Set or Map мы сначада пишем Set<...> a = new HashSet<...>(); Когда можно написать и HashSet<...> a = new HashSet<...>();?
slavqache
Скоро узнаешь. Когда мы пишем «Set» мы указываем тип файла класса-родителя. Это значит, что этой переменной мы сможем присвоить объекты любого из типов наследников класса Set.
Walmar
Спасибо!
zibul444
Но оно же значит что вернуть HashSet если указан тип при создании Set — будет не возмоно!
В общем тут или мобильность в плане перевода в любой тип класса Set, но урезаем возможности конкретного типа, или на оборот!
dimon-hacker
А как же приведение типов?
Set set=new HashSet();
HashSet set2=(HashSet) set;
zibul444
Это всё же разные классы, могут быть потери некоторой информации т.к. произойдёт сужение…
specialfor
Set<...> set = new HashSet<...>.
Set указывает на то, что объект, путь к которому хранит перемення set типа Set, будет видеть только те методы и поля, которые доступны типу Set, а HashSet — объект будет использовать переопределенные методы Set (если метод не переопределили — то он будет использовать метод Set).
Здесь есть еще один такой интересный момент, что объект не будет видеть методы HashSet, он видит только методы Set.
Объявление и инициализаци такого рода записи используеться в полиморфизме (лекция 12)
На скриншотах я попытался изобразить то, что описывал выше:
На первом скрине изображено 2 класа Man и Woman (Woman наследуеться от Man), и создается объект: Man woman = new Woman().
На втором скрине видно, что объект, на который ссылаеться перменная woman, видит только методы Man, а методы Woman (public void makeup()) ему неизвестны.
Первый скринВторой скрин
Walmar
Всё понял! Спасибо,specialfor !
Clevaster
Спасибо, очень доступно!
WhiteSteel
О-о-о. Уже два года как прошло. Но зачем это нужно, какая здесь выгода?
tesh
отличный комент. стало намного понятнее, спасибо!
varbandim
Спасибо! Наконец-то понял.
Timur
Наверно стоит добавить
Структуры данных в картинках. HashMap
Globus51
Посоветуйте пару толковых ссылок что/где ещё почитать чтобы решить задачи по теме: «Date — тип для хранения даты и времени».
panser
задавал этот вопрос к одной из задач игры, но вот ответа так и не пришло. думаю многии, как и я, в этом не разобралися. может кто из поопытнее скажет

почему, то бы пропарсить «человеческую дату», необходимо учесть "-1 месяц"

public class test1{
    public static void main(String[] args) {
        String year = "2014";
        String month = "01";
        String day = "09";

        Calendar cal = new GregorianCalendar(Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(day));
        Date birthDate = cal.getTime();

        System.out.println(birthDate);
    }
}


Sun Feb 09 00:00:00 FET 2014

а хотелось бы

Thu Jan 09 00:00:00 FET 2014
Sant9Iga
ну просто они так договорились и решили что месяцы начинаются с 0) видимо потому что там массив какой то или еще по чему то)
IvanDurov
Насколько я понял, в Java 8 будет получше
//Builder pattern used to make date object
 OffsetDateTime date1 = Year.of(2013)
                        .atMonth(Month.MAY).atDay(15)
                        .atTime(0, 0)
                        .atOffset(ZoneOffset.of("+03:00"));
 System.out.println(date1);                                     //2013-05-15T00:00+03:00
 
//factory method used to make date object
OffsetDateTime date2 = OffsetDateTime.
                        of(2013, 5, 15, 0, 0, 0, 0, ZoneOffset.of("+03:00"));
System.out.println(date2);                                      //2013-05-15T00:00+03:00
Diana
Java 8 — это, конечно, круто, но первый проект на первой работе будет, скорее всего, на java 6. И надо знать и понимать, как работает тот написанный кем-то код.
И не всегда будет возможность заменить устаревший Date на Calendar или OffsetDateTime
Sant9Iga
panser
то что надо! огромное спасибо! спать не мог.
panser
а я путался, совсем не мог увидить закономерности.
Sant9Iga
гугл)
panser
стыжусь. но до меня просто не доходило что (месяц — 1) == (месяц1 = 0)
Ruzveld
IDEA ругается на java.util.Date, мол устаревшие там методы. Приходится вслепую домашку делать, так как компилироваться такой код не хочет.
Было бы неплохо, если бы рассмотрели другой способ обращения с датами.
Ruzveld
Кстати, в задаче level08.lesson11.bonus03, где надо вывести массив строк в алфавитном порядке, подразумевается использование метода compareTo. Фактически этот метод справляется с задачей только частично, так как в таблице юникода все буквы нижнего регистра следуют за буквами верхнего. Получается, если мы введем
b
A
a
B,
то результат сортировки будет следующим:
A
B
a
b,
что нельзя назвать алфавитным порядком.
Izhak
Если хочется, то перед отправкой в метод все слова можно приводить toLowerCase или toUpperCase, но это не требуется.
Ruzveld
Это да, я просто обратил внимание но то, что тестировщик принимает заведомо неверные решения.
abusabir
Кстати, да, насчёт Date: компилятор у меня правда не ругается, но редактор помечает большинство методов как отменённые и в книге «java для начинающих» написано, что ещё в версии 1.1 был исключен этот класс Date. Дальше будет рассказано как современно решать эти задачи? )
Ruzveld
Да, на 40 уровне)
Хотя ничего не мешает сейчас почитать про класс Calendar например. Потому что задачи с его использованием будут встречаться и задолго до 40 уровня.
plyuspavel
Странно, что толком не объяснили как удалять элементы карты. Насколько было понятно из лекций, элемент можно удалить командой map.remove(key), но во всех задачах эта команда приводила к ошибке. Как оказалось, надо использовать iterator.remove(). Почему именно так?
Kashey
если я правильно понял, если удаляешь через map.remove(key), то итератор об этом не узнает.
miha-23d
  • miha-23d
  • 0
  • Комментарий отредактирован 2014-10-11 22:18:21 пользователем miha-23d
Похоже знает, попробовал сейчас, выдает:
Exception in thread "main" java.util.ConcurrentModificationException
Gpef
  • Gpef
  • 0
  • Комментарий отредактирован 2014-11-22 04:37:13 пользователем Gpef
Потому что нельзя изменять элементы карты пока ты идешь по ней итератором. тут надо удалять через:

Iterator<Map.Entry<String, String>> entry = map.entrySet().iterator();
while (entry.hasNext())
entry.remove();
werru
а ещё можно так
public static void removeItemFromMapByValue(HashMap<String, String> map, String value)
    {
        HashMap<String, String> copy = new HashMap<String, String>(map);
        for (Map.Entry<String, String> pair : copy.entrySet())
        {
            if (pair.getValue().equals(value))
                map.remove(pair.getKey());
        }

делается копия map и прогон идёт по ней. А удаление в map
buxta_baraxta
Всем привет. Ребят а растолкуйте мне вот эту запись for (Map.Entry<String, String> entry: map.entrySet()).
NazarKubliy
Говоря простым языком: в цикле for мы создаем неявным способом итератор с именем «entry»
shirik78
Удаление элемента из мапы(одинаковых значений) возможно только через итератор? И почему нужно создавать 2 копии? так и не понял, к сожалению…
Gpef
Вторая копия так и не понятно зачем )
Если ты знаешь, что нужно удалять, то можно и так (в условиях задач есть один метод такой):

public static void removeItemFromMapByValue(HashMap<String, String> map, String value)
{
HashMap<String, String> copy = new HashMap<String, String>(map);
for (Map.Entry<String, String> pair: copy.entrySet())
{
if (pair.getValue().equals(value))
map.remove(pair.getKey());
}
}
Bushrut
Очень просто все. Вы копируете вашу основную мапу в другую мапу по имени copy. И в этой копии ищете нужное Вам значение, после того как Вы его нашли, Вы получаете ключ этого значения и удаляете его из основной мапы. Так реализован цикл for each без применения итератора, т.к. в итераторе имеется определенная связь между методом next() и remove(). Метод remove() нельзя вызвать если перед ним не был вызван метод next(). Если это сделать будет сгенерировано исключение IllegalStateExcepion.
teacher5555
  • teacher5555
  • 0
  • Комментарий отредактирован 2016-07-03 16:03:56 пользователем teacher5555
Тоже долго не мог понять почему именно так. Как факт запомнил, но смысл не понял. Но потом нашел ответ в первой ссылке на этой странице, которая на Интуите. Там есть такой пример:

<code>public class Test {
  public Test() {
  }
  public static void main(String[] args) {
    Test t = new Test();
    ArrayList al = new ArrayList();
    al.add("First element");
    al.add("Second element");
    al.add("Third element");
    Iterator it = al.iterator();   // это понятно
    while(it.hasNext()) {
      System.out.println((String)it.next());
    }
    System.out.println("\n");
    al.add(2,"Insertion");
    it = al.iterator();        // зачем? Когда мы уже сделали это выше
    while(it.hasNext()){
      System.out.println((String)it.next());
    }
  }
}</code>
И вот здесь стало интересно, зачем повторно инициализировать итератор (it = al.iterator();) когда он был создан и инициализирован ранее (Iterator it = al.iterator()). Попробовал закоментить вторую инициализацию и IDEA выдала Exception.

Получается что каждый раз при изменении (добавлении/удалении элементов) Мапы, Листа и т.д. нужно каждый раз инициализировать итератор!

Помните вот этот пример в доп. лекциях 7 уровня?

<code>for (Iterator<String> iterator = list.iterator(); iterator.hasNext();{ // инициализация каждый раз при итерации
    String string = iterator.next();
    if (string.isEmpty()) {
        iterator.remove(); // ошибки не будет
    }
}</code>
Здесь на каждом шаге итерации в цикле for происходит его инициализация. Поэтому ошибки не происходит.

А в этом примере, когда мы неявно используем итератор, мы его инициализируем один раз!!! Потом удаляем элемент и пытаемся снова пройти итерацию, но так нельзя, итератор нужно снова инициализировать!

<code>public static void main(String[] args)
{
    Map<String, String> map = new HashMap<String, String>(); 
    map.put("first", "Mama");
    map.put("second", "Mila");
    map.put("third", "Ramu");

    for (Map.Entry<String, String> pair : map.entrySet()) // инициализация 1 раз!!!
    {
       map.remove(pair.getKey()); // будет ошибка!
    }
}</code>
Тогда опытные программеры подумали и решили, что если хочется использовать итератор неявным образом (лаконичней код), но при этом надо удалять или добавлять элементы, то можно создать абсолютно идентичную копию объекта. Потом итератором мы проходимся по КОПИИ объекта, а работаем (удаляем, добавляем) ОРИГИНАЛЬНЫЙ объект!

Вот код удаления элементов через неявный итератор и копию объекта:

<code>Map<String, String> map = new HashMap<String, String>();
        map.put("first", "Mama");
        map.put("second", "Mila");
        map.put("third", "Ramu");

        Map <String, String> copy = new HashMap<String, String >(map); // делаем объект "copy" - копию объекта "map" 

        for (Map.Entry<String, String> pair : copy.entrySet()) { // проходим итератором по копии
            map.remove(pair.getKey()); // а удаляем элементы из оригинального объекта map
        }</code>
// копия потом уничтожится сама.

Хитро на самом деле. Сам додумал не сразу. И кстати совет Gpefa (при всем уважении к нему):

<code>Iterator<Map.Entry<String, String>> entry = map.entrySet().iterator();
while (entry.hasNext())
entry.remove();</code>
работать не будет. Попробуйте наберите. А все потому что инициализация происходит 1 раз! В таком случае, чтобы работало нужно использовать цикл for. Правильный код:

<code>for (Iterator<Map.Entry<String, String>> entry = map.entrySet().iterator(); entry.hasNext();){
            entry.next();
            entry.remove();
        }</code>
Вывод:
1) Если хотим использовать итератор неявным способом и при этом не планируем добавлять/удалять — смело делаем это.
2) Если планируем удалять/добавлять, тогда используем итератор явным способом и помещаем его в цикл for
3) Если планируем удалять/добавлять и хотим неявным способом использовать итератор, то создаем копию объекта, проходим итератором по копии, но работаем (удаляем, добавляем) с оригинальным объектом
Kirr
  • Kirr
  • 0
zibul444
Отлично, тема нужная, и еще не тронутая! Благодарность в карму тебе))
Veb
  • Veb
  • 0
не встретил в лекциях Vector, Stack, Hashtable и некоторых других реализаций коллекций (упоминание — не в счёт)
Diana
коллекции изучаются на 30+ уровнях. А на этом уровне только обзор
zibul444
+ Здесь не все подробно описывается, а только часть что-бы въехать!
sheyl
как читать лекции? где они вообще находятся? подскажите пожалуйста
NazarKubliy
Проект JavaRush: javarush.ru/user/reference/095d9949-097d-451e-92cd-34fa14b33568
Регистрируйся и читай лекции
HayLLlHuK
Статья на хабре про HashMap
Статья на хабре про LinkedHashMap
misstos
как изучать лекции? у меня отображается только план лекции и все, никаких ссылок…
blizzard
Это и есть лекция. Тут просто упоминается то, с чем пришлось столкнуться. Дальше все сам.
Diana
лекции находятся на Javarush.ru -> Курс Java
Этот топик — дополнительный материал к лекции
sphinks_a
Все таки не понял, как использовать метод removeItemFromMapByValue в задаче level08.lesson08.task05
И стоит ли вообще использовать? Я обошелся 2 циклами и копией мапы. Искал на форуме пример использования этого метода и не нашел.
Liily
Циклом в цикле проверила наличие совпадающих имен, а этот метод удаляет всё в мап по этому переданному значению.
for (Map.Entry<String, String> pair: itr1.entrySet())
        {
            String name = pair.getValue();
            String key = pair.getKey();

            for (Map.Entry<String, String> pair_2: itr2.entrySet())
            {
                if (name.equals(pair_2.getValue()) && !key.equals(pair_2.getKey()))
                {
                   removeItemFromMapByValue(map, name);
                }
            }
        }
apache888
не забудьте почитать
ссылка
snuk
  • snuk
  • 0
Советую всем обратить внимание(я уже писал на саппорт, сказали сто создали тикет, но уже как пару месяцев-ничего не изменилось), класс Date, в нем 90% методов помечены как deprecated, на замену этому неудобному классу с 8 java пришел класс Time. Актуально изучить его, потому что проходимый тут класс устарел.
b_rhyme
snuk , в изучении depricated-классов и методов тоже есть своя прелесть, согласитесь ;) Вы будете знать и это тоже! Ведь далеко не факт, что Вы никогда не столкнетесь с методами класса Date (getSeconds, getMinutes etc. :)
snuk
Не могу конечно не согласиться, но все же стоило бы упомянуть о том, что есть иная библиотека, речь о которой пойдет позже, но это не так важно… Важно что в задачах не указано что решать надо строго с Date, потому что не компилируется с Time на сервере решение…
b_rhyme
Ну, теперь-то Вы точно знаете, что в данном курсе only Java 7 =)
teacher5555
Решал с использованием класса Calendar — валидатор принял.
snuk
Кстати, дело не в том, как надо решать, а в том что весь курс на java7, java8 просто не поддерживается. Решив задачу с новой библиотекой, теперь понимаю насколько тугая и плохая старая Date, просто дикая разница.
DenisDN
Здравствуйте, подскажите пожалуйста, что нужно дополнительно прочесть, что бы решить задачу от Боброва №5. (Написать программу, которая вводит с клавиатуры строку текста.Программа заменяет в тексте первые буквы всех слов на заглавные.)
snuk
  • snuk
  • +1
  • Комментарий отредактирован 2016-01-14 16:24:14 пользователем snuk
BufferedReader, String to chararray, equalsignorecase, equals, for, toUpperCase, toLowerCase. Понимания принципов работы названного достаточно для решения задачи, кстати она не настолько сложная, если подумать и разложить алгоритм с начала до конца по полочкам.
DenisDN
Спасибо, нужно было направление поисков. Задачу пока даже не пробовал решать, так как не было общей картины того, что надо использовать при решении. В лекциях этого не было(в большинстве), поэтому нужно было собрать больше информации
snuk
В целом в лекциях есть все это, просто это в общем-то сбор всех крупиц в одну. Тут надо решить от чего отталкиваться-отправная точка в решении задачи. Я не буду говорить от чего надо плясать, иначе и смысла не будет ее решать. Просто подумайте, что с чем сравниваете и что делаете при результатах сверки.
Mikola_Uhta
Две задачи не компилируются на сервере. Куда обращаться?
Joysi
найдите соответствующие темы:
обычно levelX.lessonY.taskZ
— и там напишите, если нет такой — создайте по аналогии.
MaxST1994
Data же вроде устаревшая коллекция, почему она до сих пор в заданиях. Альтернатива какая есть? Calendar?
kracozubr13
Где собственно лекция то?? я вижу только краткое содержание + ссылки, но самой лекции нет
VoVuS
Выше уже говорилось об этом, тут только план лекции, и доп. ссылки + обсуждение. Сами лекции нужно читать на джавараше.
JGosling
По теме посоветую почитать у Хорсманна (1том) главу про коллекции.
Сразу все вопросы прояснятся.
Ra_Vil
Ребят, помогите пожалуйста. Intellij idea зачёркивает метод getMonth() и new Date(). Ниже появляется окошко is deprecated. Кто знает что делать???
Joysi
На данном этапе не обращай внимания. Так IDEA уведомляет тебя, что данный метод помечен разработчиками как Deprecated (то есть устаревший и в будущем будет заменен чем то другим). Но тем не менее его вполне можно использовать, что и делайте.
Вообще с датами в Java немного запутанно, но со временем проясните. Более подробно habrahabr.ru/post/274811/
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.