Массивы Массивы в Java

голоса
14

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

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

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

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

Если я нахожусь в группе А, вот бы мои разрешенные раз: Зима: понедельники только весна: вт, чт, сб Лето: Any Day Fall: вт, чт, сб

Если бы я писал это в 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), (любой).

Задан 16/08/2008 в 00:07
источник пользователем
На других языках...                            


12 ответов

голоса
9

Не пытайтесь быть динамичным , как РНР. Вы могли бы попытаться первым определить , что вам нужно.

interface Season
{
    public string getDays();
}

interface User
{
    public Season getWinter();
    public Season getSpring();
    public Season getSummer();
    public Season getFall();
}

interface UserMap
{
    public User getUser(string name);
}

И , пожалуйста, прочитайте документацию Hashtable перед его использованием. Этот класс синхронизируется , что означает , что каждый вызов защищен от многопоточности , которая действительно замедляет доступ , когда вы не нуждаетесь в дополнительной защите. Пожалуйста , используйте Map реализации вместо как HashMap или TreeMap .

Ответил 16/08/2008 d 01:21
источник пользователем

голоса
8

Вы могли бы сделать по существу тот же самый код с HashTables (или какой-либо другой карте):

Hashtable<String, Hashtable<String, String>> schedule
    = new Hashtable<String, Hashtable<String, String>>();
schedule.put("A", new Hashtable<String, String>());
schedule.put("B", new Hashtable<String, String>());
schedule.put("C", new Hashtable<String, String>());
schedule.put("D", new Hashtable<String, String>());
schedule.put("E", new Hashtable<String, String>());

schedule.get("A").put("Winter", "M");
schedule.get("A").put("Spring", "tTS");
// Etc...

Не так элегантно, но опять же, Java не динамический язык, и он не имеет хэшей на уровне языка.

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

Ответил 16/08/2008 d 00:16
источник пользователем

голоса
6

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

Что-то вроде:

class Schedule
{
  private String group;
  private String season;
  private String rundays;
  public Schedule() { this.group = null; this.season = null; this.rundays= null; }
  public void setGroup(String g) { this.group = g; }
  public String getGroup() { return this.group; }
  ...
}

public ArrayList<Schedule> schedules = new ArrayList<Schedule>();
Schedule s = new Schedule();
s.setGroup(...);
...
schedules.add(s);
...

Конечно, это, вероятно, не является правильным либо. Я бы сделал каждый сезон объект, и, может быть, каждый список буднего как объект тоже. Во всяком случае, его легко использовать повторно, понят, и расширяемый, чем хромал-вместе Hashtable, который пытается имитировать ваш PHP код. Конечно, PHP есть объекты тоже, и вы должны использовать их таким же образом, вместо того, чтобы ваши убер-массивы, где это возможно. Я понимаю, соблазн обмануть, хотя. PHP делает это так легко и так весело!

Ответил 16/08/2008 d 01:28
источник пользователем

голоса
4

Вот один из способов это может выглядеть, вы можете понять остальное из:

A = new Group();
A.getSeason(Seasons.WINTER).addDay(Days.MONDAY);
A.getSeason(Seasons.SPRING).addDay(Days.TUESDAY).addDay(Days.THURSDAY);
A.getSeason(Seasons.SPRING).addDays(Days.MONDAY, Days.TUESDAY, ...);

schedule = new Schedule();
schedule.addWateringGroup( A );
Ответил 16/08/2008 d 08:37
источник пользователем

голоса
3

Я не программист Java, но деться от Java и просто думать в терминах, больше языка агностик - более рациональный способ сделать это было бы использовать либо константы или перечисленные типы. Это должно работать в любом LANGAUGE, который поддерживает многомерные массивы.

При использовании именованных констант, где, например:

int A = 0;
int B = 1;
int C = 2;
int D = 3;

int Spring = 0; 
int Summer = 1;
int Winter = 2; 
int Fall = 3;
...

Тогда константы служат более считываемых индексов массива:

schedule[A][Winter]="M";
schedule[A][Spring]="tTS";
schedule[A][Summer]="Any";
schedule[A][Fall]="tTS";
schedule[B][Winter]="t";

Использование перечисленных типов:

enum groups
{
  A = 0,
  B = 1,
  C = 2,
  D = 3
}

enum seasons
{
  Spring = 0,
  Summer = 1,
  Fall = 2,
  Winter = 3
}
...
schedule[groups.A][seasons.Winter]="M";
schedule[groups.A][seasons.Spring]="tTS";
schedule[groups.A][seasons.Summer]="Any";
schedule[groups.A][seasons.Fall]="tTS";
schedule[groups.B][seasons.Winter]="t";
Ответил 16/08/2008 d 00:56
источник пользователем

голоса
2

Я с теми, которые предлагают герметизирующего функции в объектах.

import java.util.Date;
import java.util.Map;
import java.util.Set;

public class Group {

    private String groupName;

    private Map<Season, Set<Day>> schedule;

    public String getGroupName() {
        return groupName;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

    public Map<Season, Set<Day>> getSchedule() {
        return schedule;
    }

    public void setSchedule(Map<Season, Set<Day>> schedule) {
        this.schedule = schedule;
    }

    public String getScheduleFor(Date date) {
        Season now = Season.getSeason(date);
        Set<Day> days = schedule.get(now);
        return Day.getDaysForDisplay(days);
    }

}

EDIT: Кроме того, ваши диапазоны дат не принимают високосные годы во внимание:

Наши сезоны выглядеть следующим образом: (5-1 8-31) Весна Лето (от 3-1 до 4-30) Падение (9-1 10-31) Зима (11-1 до 2-28)

Ответил 16/08/2008 d 13:04
источник пользователем

голоса
2

Я полностью в недоумении, почему некоторые из вас , кажется, думают , что бросать уйма объектов в коде путь. Например, существует ровно четыре сезона, и они не делают или хранить что - нибудь. Как это упрощает все , чтобы сделать их объектами? Крыло вполне справедливо , что они должны , вероятно , быть постоянными (или , может быть , перечислений).

Что нужно Брюс, у него сердце, это просто таблица перекодировки. Он не нуждается в иерархии объектов и интерфейсов; он нужен способ, чтобы посмотреть расписание, основанное на сезон и идентификатор группы. Что касается вещей в объекты имеет смысл только если у них есть обязанности или состояние. Если они не имеют ни, то они просто идентификаторы, а также создание специальных объектов для них просто делают кодовую больше.

Вы могли бы построить, например, Groupобъекты, каждый из которых содержит набор строк расписания ( по одному для каждого сезона), но если все Groupобъект действительно является обеспечить функциональность поиска, то вы заново таблицу поиска в гораздо менее интуитивным способом. Если он должен найти группу, а затем выполните поиск график, все , что он представляет собой таблицу поиска два шага , что заняло больше кода, более вероятно, будет глючит, и будет труднее поддерживать.

Ответил 16/08/2008 d 02:07
источник пользователем

голоса
1

Есть ли у «дата», чтобы быть параметром? Если вы просто показывать текущий график полива сам класс WateringSchedule может понять, что это день, и, следовательно, какой сезон это. Тогда просто есть метод, который возвращает карту, где ключ является буква группы. Что-то вроде:

public Map<String,List<String>> getGroupToScheduledDaysMap() {
  // instantiate a date or whatever to decide what Map to return
}

Затем на странице JSP

<c:forEach var="day" items="${scheduler.groupToScheduledDaysMap["A"]}">
   ${day}
</c:forEach>

Если вам нужно, чтобы показать графики для более чем на один сезон, вы должны иметь метод в классе WateringSchedule, который возвращает карту, где сезоны ключи, а затем Карты groupToScheduledDays являются значением.

Ответил 16/08/2008 d 05:35
источник пользователем

голоса
1

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

Использование базы данных будет гораздо легче поддерживать, и есть выбор из бесплатных баз данных двигателей на выбор.

Два из этих СУБД реализованы полностью на Java и может быть встроен в приложение, просто включая файл фляги. Это немного тяжеловесный, конечно, но это намного более масштабируемым и проще в обслуживании. Просто потому, что есть 20 записей сегодня не означает, что не будет более позднее в связи с изменением требований или признаком ползучести.

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

Ответил 16/08/2008 d 02:46
источник пользователем

голоса
1

Я согласен, что вы обязательно должны поставить эту логику чистого интерфейса:

public String lookupDays(String group, String date);

но, возможно, вы должны придерживаться данных в файле свойств. Я не против жесткого кодирования этих данных в ваших исходных файлах, но, как вы заметили, Java может быть довольно многословен, когда речь идет о вложенных коллекциях. Ваш файл может выглядеть так:

A.Summer = М
A.Spring = TTS
B.Summer = Т

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

Если вам не нравится эта идея, может быть, вы можете сделать что-то вроде этого:

public class WaterScheduler
{
  private static final Map<String, String> GROUP2SEASON = new HashMap<String, String>();
  static
  {
    addEntry("A", "Summer", "M");
    addEntry("A", "Spring", "tTS");
    addEntry("B", "Summer", "T");
  }

  private static void addEntry(String group, String season, String value)
  {
    GROUP2SEASON.put(group + "." + season, value);
  }

}

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

Ответил 16/08/2008 d 01:53
источник пользователем

голоса
0

ТЛ; др

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

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

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

Современные Java

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

Да.

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

Java.time структура , встроенная в Java предлагает Monthперечисление и DayOfWeekперечисление.

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

Вы можете определить свои собственные перечислений , чтобы представить свой сезон и ваши группы (A, B, и так далее). Перечисление объекта в Java является гораздо более полезным и мощным , чем видели на других языках. Если не знакомы, увидеть Oracle Учебник .

Простой синтаксис определения собственных перечислений фактически обеспечивает большую часть функциональности , необходимой для решения этого вопроса, устраняя некоторые сложные кодирования. Новые литералы Синтаксис для множеств и карт в методах коллекции фабрики в Java 9 ( СЭП 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

Представляет каждую группировку клиентов газоны / ярды, (А, В, С, D, Е) в качестве имени перечисления 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мы видим это сбрасывали на консоль.

Сезон: ВЕСНА = [март, апрель]

Сезон: ЛЕТО = [май, июнь, июль, август]

Сезон: ОСЕНЬ = [сентябрь, октябрь]

Сезон: Зима = [ноябрь, декабрь, январь, февраль]

Группа: А = {ВЕСНА = [вторник, четверг], ФАЛЬ = [вторник, четверг], ЛЕТО = [понедельник, вторник, среда, четверг, пятница, суббота, воскресенье], ЗИМА = [вторник]}

Группа: В = {ВЕСНА = [Пятница], ФАЛЬ = [вторник, пятница], ЛЕТО = [понедельник, вторник, среда, четверг, пятница, суббота, воскресенье], ЗИМА = [пятница]}

Группа: С = {ВЕСНА = [понедельник], ФАЛЬ = [понедельник, вторник], ЛЕТО = [понедельник, вторник, среда, четверг, пятница, суббота, воскресенье], ЗИМА = [понедельник]}

Группа: D = {ВЕСНА = [среда, пятница], ФАЛЬ = [Пятница], ЛЕТО = [понедельник, вторник, среда, четверг, пятница, суббота, воскресенье], ЗИМА = [среда]}

Группа: Е = {ВЕСНА = [вторник], ФАЛЬ = [вторник, среда], ЛЕТО = [понедельник, вторник, среда, четверг, пятница, суббота, воскресенье], ЗИМА = [среда]}

Группа А - поливочные дни на 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Класс представляет собой дату только значение без времени суток и без временной зоны.

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

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

Укажите правильное время имя зоны в формате 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 Гуава библиотеки:

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

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

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 время проект, в настоящее время в режиме технического обслуживания , советует миграции в java.time классы.

Чтобы узнать больше, обратитесь к Oracle Учебник . И поиск переполнения стека для многих примеров и объяснений. Спецификация 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, и более .

Ответил 30/01/2018 d 01:55
источник пользователем

голоса
0

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

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

и затем LookUp:

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

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

String whenCanIWater(String group, Date date) { /* ugliness here */ }
Ответил 16/08/2008 d 00:27
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more