Domanda

Questa è una cosa brutta per me...Sono un ragazzo PHP che lavora in Java su un progetto JSP.So come fare ciò che sto tentando attraverso troppo codice e una totale mancanza di finezza.

Preferirei farlo bene.Ecco la situazione:

Sto scrivendo un piccolo display per mostrare ai clienti in quali giorni possono irrigare i loro prati in base al loro gruppo di irrigazione (ABCDE) e in che periodo dell'anno è.Le nostre stagioni sono così:Summer (da 5-1 a 8-31) primavera (da 3-1 a 4-30) autunno (da 9-1 a 10-31) inverno (da 11-1 a 2-28)

Un esempio potrebbe essere:

Se fossi nel gruppo A, ecco i tempi consentiti:Inverno:Lunedì solo primavera:Martedì, giovedì, sabato estate:Ogni giorno autunno:Martedì, giovedì, sabato

Se lo scrivessi in PHP, utilizzerei array come questo:

//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';

POTREI creare gli array dei giorni (array("Tuesday","Thursday","Saturday")) ecc., ma non è necessario per quello che sto veramente cercando di realizzare.

Dovrò anche impostare gli array per determinare in quale stagione mi trovo:

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

Qualcuno può suggerire un modo davvero interessante per farlo?Avrò la data di oggi e la lettera del gruppo.Dovrò uscire dalla mia funzione per un giorno (M) o per una serie di giorni (tTS), (Qualsiasi).

È stato utile?

Soluzione

Potresti fare essenzialmente lo stesso codice con Hashtables (o qualche altra mappa):

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...

Non altrettanto elegante, ma ripeto, Java non è un linguaggio dinamico e non ha hash a livello di linguaggio.

Nota:Potresti essere in grado di trovare una soluzione migliore, questo mi è appena venuto in mente mentre leggevo la tua domanda.

Altri suggerimenti

Non cercare di essere dinamico come lo è PHP.Potresti provare prima definire quello che ti serve.

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);
}

E per favore, leggi la documentazione di Tabella hash prima di usarlo.Questa classe è sincronizzata, il che significa che ogni chiamata è protetta dal multithreading che rallenta notevolmente l'accesso quando non è necessaria una protezione aggiuntiva.Si prega di utilizzarne uno qualsiasi Carta geografica implementazione invece piace HashMap O Mappa ad albero.

Sembra che tutti stiano cercando di trovare il modo Java per farlo come se lo stessi facendo in PHP, invece del modo in cui dovrebbe essere fatto in Java.Considera semplicemente ogni pezzo del tuo array come un oggetto o, almeno, il primo livello dell'array come un oggetto e ogni sottolivello come variabili all'interno dell'oggetto.Costruisci una struttura dati da popolare con detti oggetti e accedi agli oggetti tramite gli accessori forniti della struttura dati.

Qualcosa di simile a:

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);
...

Naturalmente probabilmente non è giusto neanche questo.Renderei ogni stagione un oggetto e forse anche ogni elenco dei giorni feriali come un oggetto.Ad ogni modo, è più facilmente riutilizzabile, comprensibile ed estensibile di una Hashtable assemblata che cerca di imitare il tuo codice PHP.Naturalmente, anche PHP ha degli oggetti e dovresti usarli in modo simile al posto dei tuoi uber-array, ove possibile.Capisco però la tentazione di imbrogliare.PHP lo rende così semplice e divertente!

Ecco un modo Potevo sembra che puoi capire il resto:

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 );

Non sono un programmatore Java, ma allontanandomi da Java e pensando solo in termini più indipendenti dal linguaggio: un modo più pulito per farlo potrebbe essere quello di utilizzare costanti o tipi enumerati.Questo dovrebbe funzionare in qualsiasi linguaggio che supporti array multidimensionali.

Se si utilizzano costanti con nome, dove, ad esempio:

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

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

Quindi le costanti fungono da pedici di array più leggibili:

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

Utilizzando i tipi enumerati:

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";

Non riesco assolutamente a capire perché alcuni di voi sembrano pensare che lanciare oggetti sul codice sia la strada da percorrere.Ad esempio, ci sono esattamente quattro stagioni e non lo fanno Fare O negozio nulla.Come si semplifica qualcosa per renderli oggetti?Wing ha perfettamente ragione nel dire che probabilmente dovrebbero esserlo costanti (o forse enumerazioni).

Ciò di cui Bruce ha bisogno, in sostanza, è semplicemente una tabella di ricerca.Non ha bisogno di una gerarchia di oggetti e interfacce;ha bisogno di un modo per cercare un programma basato su una stagione e un identificatore di gruppo.Trasformare le cose in oggetti ha senso solo se hanno delle responsabilità o uno stato.Se non hanno nessuno dei due, allora sono semplicemente identificatori e la creazione di oggetti speciali per loro non fa altro che ingrandire la base di codice.

Voi Potevo costruire, ad esempio, Group oggetti che contengono ciascuno un insieme di stringhe di pianificazione (una per ogni stagione), ma se tutti i file Group object non fa altro che fornire funzionalità di ricerca, quindi hai reinventato la tabella di ricerca in un modo molto meno intuitivo.Se deve cercare il gruppo e poi la pianificazione, tutto ciò che ha è una tabella di ricerca in due passaggi che richiede più tempo per essere codificata, è più probabile che sia difettosa e sarà più difficile da mantenere.

Sono con coloro che suggeriscono di incapsulare la funzione negli oggetti.

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);
    }

}

MODIFICARE:Inoltre, gli intervalli di date non tengono conto degli anni bisestili:

Le nostre stagioni sono così:Summer (da 5-1 a 8-31) primavera (da 3-1 a 4-30) autunno (da 9-1 a 10-31) inverno (da 11-1 a 2-28)

Sono d'accordo che dovresti assolutamente mettere questa logica dietro l'interfaccia pulita di:

public String lookupDays(String group, String date);

ma forse dovresti inserire i dati in un file delle proprietà.Non sono contrario all'hardcoding di questi dati nei file sorgente ma, come hai notato, Java può essere piuttosto prolisso quando si tratta di raccolte nidificate.Il tuo file potrebbe essere simile a:

A.Estate=M
A.Primavera=tTS
B.Estate=T

Di solito non mi piace spostare i dati statici come questo in un file esterno perché aumenta la "distanza" tra i dati e il codice che li utilizza.Tuttavia, ogni volta che hai a che fare con raccolte nidificate, in particolare mappe, le cose possono diventare davvero brutte, molto velocemente.

Se non ti piace questa idea, forse puoi fare qualcosa del genere:

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);
  }

}

Perdi un po' di leggibilità ma almeno i dati sono più vicini a dove verranno utilizzati.

La "data" deve essere un parametro?Se stai semplicemente mostrando il programma di irrigazione corrente, la classe WateringSchedule stessa può capire che giorno è e quindi che stagione è.Quindi basta avere un metodo che restituisca una mappa in cui la chiave è la lettera del gruppo.Qualcosa di simile a:

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

Quindi nella pagina JSP

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

Se è necessario mostrare le pianificazioni per più di una stagione, è necessario disporre di un metodo nella classe WateringSchedule che restituisca una mappa in cui Seasons sono le chiavi e Maps of groupToScheduledDays sono i valori.

Una soluzione migliore sarebbe forse quella di inserire tutti i dati in un database, invece di codificarli nei sorgenti o utilizzare i file delle proprietà.

L'uso di un database sarà molto più semplice da mantenere e ce ne sono a varietà Di gratuito Banca dati motori tra cui scegliere.

Due di questi motori di database sono implementati interamente in Java e possono essere incorporati in un'applicazione semplicemente includendo un file jar.È un po' pesante, certo, ma è molto più scalabile e più facile da mantenere.Solo perché oggi ci sono 20 record non significa che non ce ne saranno altri in seguito a causa del cambiamento dei requisiti o dello scorrimento delle funzionalità.

Se, nel giro di poche settimane o mesi, decidi di voler aggiungere, ad esempio, restrizioni sull'irrigazione relative all'ora del giorno, sarà molto più semplice aggiungere tale funzionalità se stai già utilizzando un database.Anche se ciò non accadesse mai, hai trascorso alcune ore a imparare come incorporare un database in un'applicazione.

Non esiste una soluzione carina.Java semplicemente non fa bene cose del genere.La soluzione di Mike è praticamente il modo per farlo se vuoi stringhe come indici (chiavi).Un'altra opzione se l'impostazione dell'hash degli hash è troppo brutta è quella di aggiungere insieme le stringhe (rubate spudoratamente a Mike e modificate):

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

e poi cerca:

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

Se non sei soddisfatto della bruttezza generale (e non ti biasimo), metti tutto dietro una chiamata al metodo:

String whenCanIWater(String group, Date date) { /* ugliness here */ }

tl; dott

Utilizzando le funzionalità e le classi del linguaggio Java moderno, definisci le tue enumerazioni per rappresentare le stagioni e i gruppi.

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

Questo metodo produce a Set Di DayOfWeek enum oggetti (non semplice testo!), come DayOfWeek.TUESDAY & DayOfWeek.THURSDAY.

Giava moderna

Qualcuno può suggerire un modo davvero interessante per farlo?

SÌ.

Modern Java dispone di classi, raccolte ed enumerazioni integrate per aiutarti con questo problema.

IL java.time framework integrato in Java offre il Month enum e DayOfWeek enum.

IL EnumSet E EnumMap fornire implementazioni di Set E Map ottimizzati per l'uso con enumerazioni per un'esecuzione rapida con pochissima memoria.

Puoi definire il tuo enumerazioni per rappresentare la tua stagione e i tuoi gruppi (A, B e così via).La funzione enum in Java è molto più utile e potente di quella vista in altri linguaggi.Se non ti è familiare, consulta il Tutorial sull'Oracolo.

La semplice sintassi per definire le proprie enumerazioni fornisce in realtà gran parte delle funzionalità necessarie per risolvere questa domanda, eliminando alcune codifiche complicate.Nuovo sintassi letterale per set e mappe in metodi di fabbrica delle collezioni in Giava 9 (PEC 269) rende il codice ancora più semplice ora.

Ecco un'app completa e funzionante. Nota quanto poco codice c'è per gli algoritmi.La definizione delle tue enumerazioni personalizzate svolge la maggior parte del lavoro pesante.

Un avvertimento con questo codice dell'app:Si presuppone che non cambi nulla nelle definizioni della tua attività, o almeno se c'è un cambiamento che ti interessa solo delle regole attuali, "l'ultimo è il migliore".Se le tue regole cambiano nel tempo e devi rappresentare tutte le versioni passate, presenti e future, creerei un'app molto diversa, probabilmente con un database per archiviare le regole.Ma questa app qui risolve la domanda come richiesto.

Season

Rappresenta la tua stagione come un'enumerazione Season.Ogni oggetto stagione contiene a List Di Month enum oggetti che definiscono la durata di quella particolare stagione.Il nuovo List.of la sintassi aggiunta a Java 9 definisce un elenco immutabile in una sintassi letterale tramite metodi factory statici.

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

Rappresenta ciascun gruppo di prati/cortile dei clienti (A, B, C, D, E) come un'enumerazione denominata Group.Ciascuno di questi oggetti enum contiene a Map, mappando a Season enum oggetto a a Set Di DayOfWeek oggetti enum.Per esempio, Group.A In Season.SPRING consente l'irrigazione per due giorni, 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

Metti tutto insieme in questo Schedule classe.

Questa classe utilizza le due enumerazioni definite sopra per svolgere un lavoro utile.L'unico metodo implementato finora indica quali giorni della settimana sono consentiti per un particolare gruppo in una determinata data.Il metodo determina quale Season vale per quella data.

Corri il main metodo qui per scaricare il contenuto delle nostre due enumerazioni e riferire sui giorni della settimana consentendo l'irrigazione in ciascun gruppo per una particolare data codificata.

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 );
        }
    }
}

Consolle

Durante la corsa Schedule.main, lo vediamo scaricato sulla console.

Stagione:PRIMAVERA = [MARZO, APRILE]

Stagione:ESTATE = [MAGGIO, GIUGNO, LUGLIO, AGOSTO]

Stagione:AUTUNNO = [SETTEMBRE, OTTOBRE]

Stagione:INVERNO = [NOVEMBRE, DICEMBRE, GENNAIO, FEBBRAIO]

Gruppo:A = {PRIMAVERA=[MARTEDÌ, GIOVEDÌ], AUTUNNO=[MARTEDÌ, GIOVEDÌ], ESTATE=[LUNEDI, MARTEDÌ, MERCOLEDI, GIOVEDÌ, VENERDÌ, SABATO, DOMENICA], INVERNO=[MARTEDÌ]}

Gruppo:B = {PRIMAVERA=[VENERDI], AUTUNNO=[MARTEDÌ, VENERDÌ], ESTATE=[LUNEDI, MARTEDÌ, MERCOLEDI, GIOVEDÌ, VENERDÌ, SABATO, DOMENICA], INVERNO=[VENERDÌ]}

Gruppo:C = {PRIMAVERA=[LUNEDI], AUTUNNO=[LUNEDI, MARTEDÌ], ESTATE=[LUNEDI, MARTEDÌ, MERCOLEDI, GIOVEDI, VENERDÌ, SABATO, DOMENICA], INVERNO=[LUNEDI]}

Gruppo:D = {PRIMAVERA=[MERCOLEDÌ, VENERDÌ], AUTUNNO=[VENERDÌ], ESTATE=[LUNEDI, MARTEDÌ, MERCOLEDI, GIOVEDÌ, VENERDÌ, SABATO, DOMENICA], INVERNO=[MERCOLEDÌ]}

Gruppo:E = {PRIMAVERA=[MARTEDÌ], AUTUNNO=[MARTEDÌ, MERCOLEDÌ], ESTATE=[LUNEDI, MARTEDÌ, MERCOLEDI, GIOVEDÌ, VENERDÌ, SABATO, DOMENICA], INVERNO=[MERCOLEDÌ]}

Gruppo A – Giorni irrigui della settimana 2018-01-30 n. 2018-W05 è:[MARTEDÌ]

Gruppo B – Giorni irrigui della settimana 2018-01-30 n. 2018-W05 è:[VENERDÌ]

Gruppo C – Giorni irrigui della settimana 2018-01-30 n. 2018-W05 è:[LUNEDI]

Gruppo D – Giorni irrigui della settimana 2018-01-30 n. 2018-W05 è:[MERCOLEDÌ]

Gruppo E – Giorni irrigui della settimana 2018-01-30 n. 2018-W05 è:[MERCOLEDÌ]

Settimana ISO 8601

Potresti trovare utile conoscere il ISO8601 norma per a definizione di settimana.Lo standard attribuisce un significato specifico alla “settimana” e definisce un formato testuale per rappresentare una settimana particolare o un giorno particolare all'interno di quella settimana.

Per lavorare con tali settimane in Java, considera l'aggiunta del file Tredieci-Extra libreria al tuo progetto per utilizzare il file YearWeek classe.

LocalDate

IL LocalDate La classe rappresenta un valore di sola data senza ora del giorno e senza fuso orario.

Il fuso orario è fondamentale per determinare una data.In ogni dato momento, la data varia in tutto il mondo in base alla zona.Ad esempio, pochi minuti dopo la mezzanotte Parigi, Francia è un nuovo giorno mentre è ancora “ieri”. Montreal, Quebec.

Se non viene specificato alcun fuso orario, la JVM applica implicitamente il fuso orario predefinito corrente.Tale impostazione predefinita può cambiare in qualsiasi momento, quindi i risultati potrebbero variare.È meglio specificare esplicitamente il fuso orario desiderato/previsto come argomento.

Specificare a nome corretto del fuso orario nel formato di continent/region, ad esempio America/Montreal, Africa/Casablanca, O Pacific/Auckland.Non utilizzare mai l'abbreviazione di 3-4 lettere come EST O IST come sono non fusi orari reali, non standardizzati e nemmeno unici (!).

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

Se desideri utilizzare il fuso orario predefinito corrente della JVM, richiedilo e passalo come argomento.Se omesso, l'impostazione predefinita corrente della JVM viene applicata implicitamente.Meglio essere espliciti.

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

Oppure specifica una data.Puoi impostare il mese tramite un numero, con una numerazione sensata da 1 a 12 per gennaio-dicembre.

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.

O meglio, usa il Month enum oggetti predefiniti, uno per ogni mese dell'anno.Mancia:Usa questi Month oggetti in tutta la base di codice anziché un semplice numero intero per rendere il codice più autodocumentante, garantire valori validi e fornire sicurezza del tipo.

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

Collezioni immutabili

Gli elenchi, i set e le mappe visti sopra dovrebbero idealmente essere raccolte immutabili, poiché è probabile che la modifica dell'appartenenza a tali raccolte sia confusa ed errata.

La nuova sintassi Java 9 List.of E Map.of sono già promessi come immutabili.Tuttavia, nel nostro caso il Map dovrebbe idealmente essere un EnumMap per l'efficienza delle prestazioni e della memoria.L'attuale implementazione di Map.of E Set.of apparentemente non rilevano l'uso di enumerazioni come membri e ottimizzano automaticamente con un uso interno di EnumMap E EnumSet.È stato aperto un problema OpenJDK per considerare tali problemi: prendere in considerazione miglioramenti a EnumMap e EnumSet.

Un modo per ottenere un EnumSet immutabile e un EnumMap immutabile è tramite il file Google Guava biblioteca:

I risultati di ciascuno utilizzano un sottostante EnumSet/EnumMap.Operazioni come get E put lanciare un'eccezione.In questo modo ottieni le ottimizzazioni relative all'enumerazione insieme all'immutabilità.

Ecco i Season E Group classi viste sopra modificate per utilizzare la libreria Google Guava 23.6.

Season con immutabilità

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 con immutabilità

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() );
        }
    }

}

Informazioni su Java.time

IL java.time framework è integrato in Java 8 e versioni successive.Queste classi soppiantano quelle vecchie e fastidiose eredità classi data-ora come java.util.Date, Calendar, & SimpleDateFormat.

IL Joda-Time progetto, ora in Modalità di manutenzione, consiglia la migrazione al java.time classi.

Per saperne di più, vedere il Tutorial sull'Oracolo.E cerca Stack Overflow per molti esempi e spiegazioni.La specifica è JSR310.

Dove ottenere le classi java.time?

  • JavaSE8, JavaSE9, e più tardi
    • Integrato.
    • Parte dell'API Java standard con un'implementazione in bundle.
    • Java 9 aggiunge alcune funzionalità e correzioni minori.
  • JavaSE6 E JavaSE7
    • Gran parte della funzionalità java.time è retroportata su Java 6 e 7 in ThreeTen-Backport.
  • Androide
    • Versioni successive delle implementazioni dei bundle Android delle classi java.time.
    • Per le versioni precedenti di Android, il TredieciABP il progetto si adatta ThreeTen-Backport (menzionato sopra).Vedere Come utilizzare ThreeTenABP....

IL Tredieci-Extra il progetto estende java.time con classi aggiuntive.Questo progetto è un banco di prova per possibili future aggiunte a java.time.Potresti trovare alcune classi utili qui come Interval, YearWeek, YearQuarter, E Di più.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top