Массивы массивов в Java - PullRequest
       50

Массивы массивов в Java

14 голосов
/ 16 августа 2008

Это неприятно для меня ... Я - парень из PHP, работающий на Java над проектом JSP. Я знаю, как делать то, что я пытаюсь, используя слишком много кода и полное отсутствие изящества.

Я бы предпочел сделать это правильно. Вот ситуация:

Я пишу небольшой дисплей, чтобы показать клиентам, в какие дни они могут поливать газоны в зависимости от своей группы полива (ABCDE) и в какое время года. Наши сезоны выглядят так: Лето (с 5-1 до 8-31) Весна (с 3-1 до 4-30) Осень (с 9-1 до 10-31) Зима (с 11-1 до 2-28)

Примером может быть:

Если я в группе А, вот мои разрешенные времена: Зима: только по понедельникам Весна: вторник, четверг, суббота Лето: любой день Осень: вт, четверг, сб

Если бы я писал это на PHP, я бы использовал такие массивы:

//M=Monday,t=Tuesday,T=Thursday.... etc
$schedule["A"]["Winter"]='M';
$schedule["A"]["Spring"]='tTS';
$schedule["A"]["Summer"]='Any';
$schedule["A"]["Fall"]='tTS';
$schedule["B"]["Winter"]='t';

Я МОГУ сделать массивы дней (массив («вторник», «четверг», «суббота»)) и т. Д., Но это не обязательно для того, что я действительно пытаюсь выполнить.

Мне также нужно настроить массивы, чтобы определить, в какое время года я нахожусь:

$seasons["Summer"]["start"]=0501;
$seasons["Summer"]["end"]=0801;

Кто-нибудь может предложить действительно крутой способ сделать это? У меня будет сегодняшняя дата и групповое письмо. Мне нужно будет выходить из функции один день (M) или ряд дней (TTS), (Любой).

Ответы [ 12 ]

0 голосов
/ 30 января 2018

ТЛ; др

Используя современные функции и классы языка Java, определите свои собственные перечисления для представления сезонов и групп.

Schedule.daysForGroupOnDate( 
    Group.D , 
    LocalDate.now()
)  

Этот метод возвращает Set из DayOfWeek перечисляемых объектов (не просто текста!), Таких как DayOfWeek.TUESDAY & DayOfWeek.THURSDAY.

Современная Java

Кто-нибудь может предложить действительно крутой способ сделать это?

Да.

Современная Java имеет встроенные классы, коллекции и перечисления, чтобы помочь вам с этой проблемой.

Встроенный в Java фреймворк java.time предлагает перечисление Month и перечисление DayOfWeek.

EnumSet и EnumMap предоставляют реализации Set и Map, оптимизированные для использования с перечислениями для быстрого выполнения в очень маленькой памяти.

Вы можете определить свои перечисления для представления своего сезона и своих групп (A, B и т. Д.). Функция enum в Java гораздо более полезна и мощна, чем в других языках. Если вы не знакомы, см. Oracle Tutorial .

Простой синтаксис определения ваших собственных перечислений фактически обеспечивает большую часть функциональности, необходимой для решения этого Вопроса, устраняя некоторые сложные кодирования. Новый синтаксис литералов для наборов и карт в методах фабрики в Java 9 ( JEP 269 ) делает код еще проще.

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

Одно предупреждение с этим кодом приложения: оно предполагает, что ничего не изменится в определениях вашего бизнеса, или, по крайней мере, если есть изменение, которое вас волнует только в текущих правилах, «последнее - самое большое». Если ваши правила со временем меняются и вам необходимо представлять все прошлые, настоящие и будущие версии, я бы создал совсем другое приложение, возможно, с базой данных для хранения правил. Но это приложение здесь решает вопрос, как задано.

Season

Представьте свой сезон как перечисление Season. Каждый объект сезона содержит объекты перечисления List из Month, которые определяют продолжительность этого конкретного сезона. Новый синтаксис List.of, добавленный в Java 9, определяет неизменный список в синтаксисе литералов с помощью статических фабричных методов.

package com.basilbourque.watering;

import java.time.LocalDate;
import java.time.Month;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;

public enum Season
{
    SPRING( List.of( Month.MARCH , Month.APRIL ) ),
    SUMMER( List.of( Month.MAY , Month.JUNE, Month.JULY , Month.AUGUST ) ),
    FALL( List.of( Month.SEPTEMBER , Month.OCTOBER ) ),
    WINTER( List.of( Month.NOVEMBER , Month.DECEMBER , Month.JANUARY , Month.FEBRUARY ) );

    private List< Month > months;

    // Constructor
    Season ( List < Month > monthsArg )
    {
        this.months = monthsArg;
    }

    public List < Month > getMonths ( )
    {
        return this.months;
    }

    // For any given month, determine the season.
    static public Season ofLocalMonth ( Month monthArg )
    {
        Season s = null;
        for ( Season season : EnumSet.allOf( Season.class ) )
        {
            if ( season.getMonths().contains( monthArg ) )
            {
                s = season;
                break; // Bail out of this FOR loop.
            }
        }
        return s;
    }

    // For any given date, determine the season.
    static public Season ofLocalDate ( LocalDate localDateArg )
    {
        Month month = localDateArg.getMonth();
        Season s = Season.ofLocalMonth( month );
        return s;
    }

    // Run `main` for demo/testing.
    public static void main ( String[] args )
    {
        // Dump all these enum objects to console.
        for ( Season season : EnumSet.allOf( Season.class ) )
        {
            System.out.println( "Season: " + season.toString() + " = " + season.getMonths() );
        }
    }
}

Group

Представляет каждую группу газонов / дворов клиентов (A, B, C, D, E) как перечисление с именем Group. Каждый из этих объектов перечисления содержит Map, сопоставляя объект перечисления Season с Set из DayOfWeek объектов перечисления. Например, Group.A в Season.SPRING позволяет поливать в течение двух дней, DayOfWeek.TUESDAY & DayOfWeek.THURSDAY.

package com.basilbourque.watering;

import java.time.DayOfWeek;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;

public enum Group
{
    A(
            Map.of(
                    Season.SPRING , EnumSet.of( DayOfWeek.TUESDAY , DayOfWeek.THURSDAY ) ,
                    Season.SUMMER , EnumSet.allOf( DayOfWeek.class ) ,
                    Season.FALL , EnumSet.of( DayOfWeek.TUESDAY , DayOfWeek.THURSDAY ) ,
                    Season.WINTER , EnumSet.of( DayOfWeek.TUESDAY )
            )
    ),
    B(
            Map.of(
                    Season.SPRING , EnumSet.of( DayOfWeek.FRIDAY ) ,
                    Season.SUMMER , EnumSet.allOf( DayOfWeek.class ) ,
                    Season.FALL , EnumSet.of( DayOfWeek.TUESDAY , DayOfWeek.FRIDAY ) ,
                    Season.WINTER , EnumSet.of( DayOfWeek.FRIDAY )
            )
    ),
    C(
            Map.of(
                    Season.SPRING , EnumSet.of( DayOfWeek.MONDAY ) ,
                    Season.SUMMER , EnumSet.allOf( DayOfWeek.class ) ,
                    Season.FALL , EnumSet.of( DayOfWeek.MONDAY , DayOfWeek.TUESDAY ) ,
                    Season.WINTER , EnumSet.of( DayOfWeek.MONDAY )
            )
    ),
    D(
            Map.of(
                    Season.SPRING , EnumSet.of( DayOfWeek.WEDNESDAY , DayOfWeek.FRIDAY ) ,
                    Season.SUMMER , EnumSet.allOf( DayOfWeek.class ) ,
                    Season.FALL , EnumSet.of( DayOfWeek.FRIDAY ) ,
                    Season.WINTER , EnumSet.of( DayOfWeek.WEDNESDAY )
            )
    ),
    E(
            Map.of(
                    Season.SPRING , EnumSet.of( DayOfWeek.TUESDAY ) ,
                    Season.SUMMER , EnumSet.allOf( DayOfWeek.class ) ,
                    Season.FALL , EnumSet.of( DayOfWeek.TUESDAY , DayOfWeek.WEDNESDAY ) ,
                    Season.WINTER , EnumSet.of( DayOfWeek.WEDNESDAY )
            )
    );

    private Map < Season, Set < DayOfWeek > > map;

    // Constructor
    Group ( Map < Season, Set < DayOfWeek > > mapArg )
    {
        this.map = mapArg;
    }

    // Getter
    private Map < Season, Set < DayOfWeek > > getMapOfSeasonToDaysOfWeek() {
        return this.map ;
    }

    // Retrieve the DayOfWeek set for this particular Group.
    public Set<DayOfWeek> daysForSeason (Season season ) {
        Set<DayOfWeek> days =   this.map.get( season ) ; // Retrieve the value (set of days) for this key (a season) for this particular grouping of lawns/yards.
        return days;
    }



    // Run `main` for demo/testing.
    public static void main ( String[] args )
    {
        // Dump all these enum objects to console.
        for ( Group group : EnumSet.allOf( Group.class ) )
        {
            System.out.println( "Group: " + group.toString() + " = " + group.getMapOfSeasonToDaysOfWeek() );
        }
    }

}

Schedule

Соберите все вместе в этом Schedule классе.

Этот класс использует два перечисленных выше перечисления для выполнения полезной работы. Единственный реализованный метод покажет вам, какие дни недели разрешены для определенной группы на определенную дату. Метод определяет, какой Season применяется на эту дату.

Запустите здесь метод main, чтобы выгрузить содержимое наших двух перечислений и сообщить о днях недели, в которые допускается полив в каждой группе для конкретной даты с жестким кодом.

package com.basilbourque.watering;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.time.temporal.IsoFields;
import java.util.EnumSet;
import java.util.Set;

public class Schedule
{
    static private DateTimeFormatter isoWeekFormatter = DateTimeFormatter.ofPattern( "uuuu-'W'ww" ) ;

    static public Set < DayOfWeek > daysForGroupOnDate ( Group group , LocalDate localDate )
    {
        Season season = Season.ofLocalDate( localDate );
        Set < DayOfWeek > days = group.daysForSeason( season );
        return days;
    }

    // Run `main` for demo/testing.
    public static void main ( String[] args )
    {
        Season.main( null  );
        Group.main( null  );
        // Dump all these enum objects to console.
        for ( Group group : EnumSet.allOf( Group.class ) )
        {
            LocalDate localDate = LocalDate.now( ZoneId.of( "Africa/Tunis" ) );
            Set < DayOfWeek > days = Schedule.daysForGroupOnDate( group , localDate );
            String week = localDate.format( Schedule.isoWeekFormatter  ) ; // Standard ISO 8601 week, where week number one has the first Thursday of the calendar year, and week starts on Monday, so year is either 52 or 53 weeks long.
            String message = "Group " + group + " – Watering days on " + localDate + " week # " + week + " is: " + days;
            System.out.println( message );
        }
    }
}

Консоль

При запуске Schedule.main мы видим, что это выводится на консоль.

Сезон: ВЕСНА = [МАРТ, АПРЕЛЬ]

Сезон: ЛЕТО = [МАЙ, ИЮНЬ, ИЮЛЬ, АВГУСТ]

Сезон: ОСЕНЬ = [СЕНТЯБРЬ, ОКТЯБРЬ]

Сезон: ЗИМА = [НОЯБРЬ, ДЕКАБРЬ, ЯНВАРЬ, ФЕВРАЛЬ]

Группа: A = {SPRING = [ВТОРНИК, ЧЕТВЕРГ], FALL = [ВТОРНИК, ЧЕТВЕРГ], ЛЕТО = = ПОНЕДЕЛЬНИК, ВТОРНИК, СРЕДА, СУББОТА, ПЯТНИЦА, СУББОТА, ВОСКРЕСЕНЬ], ВТОРНИК =] }26 *

Группа: B = {SPRING = [ПЯТНИЦА], FALL = [ВТОРНИК, ПЯТНИЦА], ЛЕТО = = понедельник, вторник, среда, четверг, пятница, суббота, воскресенье], зима = [пятница]}

Группа: C = {SPRING = [ПОНЕДЕЛЬНИК], FALL = [ПОНЕДЕЛЬНИК, ВТОРНИК], ЛЕТО = = ПОНЕДЕЛЬНИК, ВТОРНИК, СРЕДА, ЧЕТВЕРГ, ПЯТНИЦА, СУББОТА, Воскресенье], ЗИМА = [ПОНЕДЕЛЬНИК]}

Группа: D = {SPRING = [СРЕДА, ПЯТНИЦА], FALL = [ПЯТНИЦА], ЛЕТО = = понедельник, вторник, среда, четверг, четверг, пятница, суббота, воскресенье], зима = [среда]}

Группа: E = {SPRING = [ВТОРНИК], FALL = [ВТОРНИК, СРЕДА], ЛЕТО = = понедельник, вторник, среда, четверг, пятница, суббота, воскресенье], зима = [среда * 11]] *

Группа A - Дни полива на 2018-01-30 неделе # 2018-W05: [ВТОРНИК]

Группа B - дни полива на 2018-01-30 неделе # 2018-W05: [пятница]

Группа C - Дни полива на 2018-01-30 неделе # 2018-W05: [ПОНЕДЕЛЬНИК]

Группа D - дни полива на 2018-01-30 неделе # 2018-W05: [СРЕДА]

Группа E - Дни полива на 2018-01-30 неделе # 2018-W05: [СРЕДА]

ISO 8601 неделя

Может оказаться полезным узнать о стандарте ISO 8601 для определения недели . Стандарт придает определенное значение «неделе» и определяет текстовый формат для представления конкретной недели или определенного дня в пределах этой недели.

Для работы с такими неделями в Java рассмотрите возможность добавления библиотеки ThreeTen-Extra в свой проект, чтобы использовать класс YearWeek.

LocalDate

Класс LocalDate представляет значение только для даты без времени суток и без часового пояса.

Часовой пояс имеет решающее значение при определении даты. В любой момент времени дата меняется по всему земному шару в зависимости от зоны. Например, через несколько минут после полуночи в Париж Франция - это новый день, хотя еще «вчера» в Монреаль Квебек .

Если часовой пояс не указан, JVM неявно применяет свой текущий часовой пояс по умолчанию. Это значение по умолчанию может измениться в любой момент, поэтому ваши результаты могут отличаться. Лучше явно указать желаемый / ожидаемый часовой пояс в качестве аргумента.

Укажите собственное имя часового пояса в формате continent/region, например America/Montreal, Africa/Casablanca или Pacific/Auckland. Никогда не используйте 3-4-буквенное сокращение, например EST или IST, так как они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

Если вы хотите использовать текущий часовой пояс JVM по умолчанию, запросите его и передайте в качестве аргумента. Если опущено, текущее значение по умолчанию JVM применяется неявно. Лучше быть явным.

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

Или укажите дату. Вы можете установить месяц по номеру, с нормальным номером 1-12 для января-декабря.

LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ;  // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.

Или, лучше, использовать предварительно определенные объекты перечисления Month, по одному на каждый месяц года. Совет: используйте эти Month объекты по всей вашей кодовой базе, а не просто целое число, чтобы сделать ваш код более самодокументируемым, обеспечить допустимые значения и обеспечить безопасность типов .

LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;

Неизменяемые коллекции

Списки, наборы и карты, представленные выше, в идеале должны быть неизменяемыми коллекциями, так как изменение членства в этих коллекциях может привести к путанице и ошибочности.

Новый синтаксис Java 9 List.of и Map.of уже обещан неизменным. Однако в нашем случае Map в идеале должно быть EnumMap для эффективности производительности и памяти. Текущая реализация Map.of и Set.of, по-видимому, не обнаруживает использование перечислений в качестве элементов и автоматически оптимизируется при внутреннем использовании EnumMap и EnumSet. Существует проблема OpenJDK, открытая для рассмотрения таких проблем: учитывает усовершенствования EnumMap и EnumSet .

Один из способов получения неизменяемого EnumSet и неизменяемого EnumMap - через библиотеку Google Guava :

Результаты EACh использовать базовый EnumSet / EnumMap. Такие операции, как get и put выдают исключение. Таким образом, вы получаете оптимизацию, связанную с enum, и неизменяемость.

Вот классы Season и Group, которые мы видели выше, модифицированные для использования библиотеки Google Guava 23.6.

Season с неизменяемостью

package com.basilbourque.watering;

import java.time.LocalDate;
import java.time.Month;
import java.util.EnumSet;
import java.util.List;

public enum Season
{
    SPRING( List.of( Month.MARCH , Month.APRIL ) ),  // `List.of` provides literals-style syntax, and returns an immutable `List`. New in Java 9.
    SUMMER( List.of( Month.MAY , Month.JUNE, Month.JULY , Month.AUGUST ) ),
    FALL( List.of( Month.SEPTEMBER , Month.OCTOBER ) ),
    WINTER( List.of( Month.NOVEMBER , Month.DECEMBER , Month.JANUARY , Month.FEBRUARY ) );

    private List< Month > months;

    // Constructor
    Season ( List < Month > monthsArg )
    {
        this.months = monthsArg;
    }

    public List < Month > getMonths ( )
    {
        return this.months;
    }

    // For any given month, determine the season.
    static public Season ofLocalMonth ( Month monthArg )
    {
        Season s = null;
        for ( Season season : EnumSet.allOf( Season.class ) )
        {
            if ( season.getMonths().contains( monthArg ) )
            {
                s = season;
                break; // Bail out of this FOR loop.
            }
        }
        return s;
    }

    // For any given date, determine the season.
    static public Season ofLocalDate ( LocalDate localDateArg )
    {
        Month month = localDateArg.getMonth();
        Season s = Season.ofLocalMonth( month );
        return s;
    }

    // Run `main` for demo/testing.
    public static void main ( String[] args )
    {
        // Dump all these enum objects to console.
        for ( Season season : EnumSet.allOf( Season.class ) )
        {
            System.out.println( "Season: " + season.toString() + " = " + season.getMonths() );
        }
    }
}

Group с неизменяемостью

package com.basilbourque.watering;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

import java.time.DayOfWeek;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;

public enum Group
{
    A(
            Maps.immutableEnumMap(
                    Map.of(  // `Map.of` provides literals-style syntax, and returns an immutable `Map`. New in Java 9.
                            Season.SPRING , Sets.immutableEnumSet( DayOfWeek.TUESDAY , DayOfWeek.THURSDAY ) ,
                            Season.SUMMER , Sets.immutableEnumSet( EnumSet.allOf( DayOfWeek.class ) ) ,
                            Season.FALL , Sets.immutableEnumSet( DayOfWeek.TUESDAY , DayOfWeek.THURSDAY ) ,
                            Season.WINTER , Sets.immutableEnumSet( DayOfWeek.TUESDAY )
                    )
            )
    ),

    B(
            Maps.immutableEnumMap(
                    Map.of(
                            Season.SPRING , Sets.immutableEnumSet( DayOfWeek.FRIDAY ) ,
                            Season.SUMMER , Sets.immutableEnumSet( EnumSet.allOf( DayOfWeek.class ) ) ,
                            Season.FALL , Sets.immutableEnumSet( DayOfWeek.TUESDAY , DayOfWeek.FRIDAY ) ,
                            Season.WINTER , Sets.immutableEnumSet( DayOfWeek.FRIDAY )
                    )
            )
    ),

    C(
            Maps.immutableEnumMap(
                    Map.of(
                            Season.SPRING , Sets.immutableEnumSet( DayOfWeek.MONDAY ) ,
                            Season.SUMMER , Sets.immutableEnumSet( EnumSet.allOf( DayOfWeek.class ) ) ,
                            Season.FALL , Sets.immutableEnumSet( DayOfWeek.MONDAY , DayOfWeek.TUESDAY ) ,
                            Season.WINTER , Sets.immutableEnumSet( DayOfWeek.MONDAY )
                    )
            )
    ),

    D(
            Maps.immutableEnumMap(
                    Map.of(
                            Season.SPRING , Sets.immutableEnumSet( DayOfWeek.WEDNESDAY , DayOfWeek.FRIDAY ) ,
                            Season.SUMMER , Sets.immutableEnumSet( EnumSet.allOf( DayOfWeek.class ) ) ,
                            Season.FALL , Sets.immutableEnumSet( DayOfWeek.FRIDAY ) ,
                            Season.WINTER , Sets.immutableEnumSet( DayOfWeek.WEDNESDAY )
                    )
            )
    ),

    E(
            Maps.immutableEnumMap(
                    Map.of(
                            Season.SPRING , Sets.immutableEnumSet( DayOfWeek.TUESDAY ) ,
                            Season.SUMMER , Sets.immutableEnumSet( EnumSet.allOf( DayOfWeek.class ) ) ,
                            Season.FALL , Sets.immutableEnumSet( EnumSet.of( DayOfWeek.TUESDAY , DayOfWeek.WEDNESDAY ) ) ,
                            Season.WINTER , Sets.immutableEnumSet( DayOfWeek.WEDNESDAY )
                    )
            )
    );

    private Map < Season, Set < DayOfWeek > > map;

    // Constructor
    Group ( Map < Season, Set < DayOfWeek > > mapArg )
    {
        this.map = mapArg;
    }

    // Getter
    private Map < Season, Set < DayOfWeek > > getMapOfSeasonToDaysOfWeek ( )
    {
        return this.map;
    }

    // Retrieve the DayOfWeek set for this particular Group.
    public Set < DayOfWeek > daysForSeason ( Season season )
    {
        Set < DayOfWeek > days = this.map.get( season ); // Retrieve the value (set of days) for this key (a season) for this particular grouping of lawns/yards.
        return days;
    }

    // Run `main` for demo/testing.
    public static void main ( String[] args )
    {
        // Dump all these enum objects to console.
        for ( Group group : EnumSet.allOf( Group.class ) )
        {
            System.out.println( "Group: " + group.toString() + " = " + group.getMapOfSeasonToDaysOfWeek() );
        }
    }

}

О java.time

Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar и & SimpleDateFormat.

Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .

Где получить классы java.time?

  • Java SE 8 , Java SE 9 и выше
    • Встроенный.
    • Часть стандартного Java API с комплексной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии Android связывают реализации классов java.time.
    • Для более ранних версий Android проект ThreeTenABP адаптируется ThreeTen-Backport (упоминалось выше). См. Как использовать ThreeTenABP… .

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval, YearWeek, YearQuarter и more .

0 голосов
/ 16 августа 2008

Красивого решения не существует. Java просто не делает такие вещи хорошо. Решение Майка - в значительной степени способ сделать это, если вы хотите использовать строки в качестве индексов (ключей). Другой вариант, если настройка хеш-хэшей слишком уродлива, - это добавить строки вместе (бесстыдно украденные у Майка и модифицированные):

Hashtable<String, String> schedule = new Hashtable<String, String>();
schedule.put("A-Winter", "M");
schedule.put("A-Spring", "tTS");

и затем поиск:

String val = schedule.get(group + "-" + season);

Если вы недовольны общим безобразием (и я вас не виню), все это стоит за вызовом метода:

String whenCanIWater(String group, Date date) { /* ugliness here */ }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...