Java Dizileri Diziler

16 Cevap java

Bu benim için bir kötü biri olduğunu ... Ben bir JSP proje üzerinde Java çalışan bir PHP adam değilim. Ben çok fazla kod ve incelik tam bir eksikliği ile çalışılıyor ne yapacağını biliyorum. Ben SAĞ yapmayı tercih ediyorum. :) İşte durum:

I'm writing a small display to show customers what days they can water their lawns based on their watering group (ABCDE) and what time of year it is. Our seasons look like this: Summer (5-1 to 8-31) Spring (3-1 to 4-30) Fall (9-1 to 10-31) Winter (11-1 to 2-28)

Bir örnek olabilir:

If I'm in group A, here would be my allowed times: Winter: Mondays only Spring: Tues, Thurs, Sat Summer: Any Day Fall: Tues, Thurs, Sat

PHP bu yazı eğer böyle diziler kullanabilirsiniz:

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

Ben gün diziler (array ("Salı", "Perşembe", "Cumartesi") vb) yapabilir, ama ben gerçekten başarmak için çalışıyorum ne için gerekli değildir.

Ben de değilim ne mevsim belirlemek için kurulum diziler gerekir:

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

Herkes bunu yapmak için çok güzel bir yol önerebilir? Ben bugünün tarihini ve grup harfi olacaktır. I (Herhangi), benim işlevi dışında bir gün (M) veya gün bir dizi (TTS) almak gerekir.

Teşekkürler, millet!

16 Cevap

Siz aslında Hashtables (veya başka bir harita) ile aynı kodu yapabilirdi:

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

Gibi zarif değil, ama sonra tekrar, Java dinamik bir dil değildir, ve dil düzeyine sağlamalarının yok.

Not: Daha iyi bir çözüm yapmak mümkün olabilir, bu senin soruyu okurken sadece benim kafamda attı.

PHP gibi dinamik olmaya çalışmayın. Önce define ihtiyacınız ne deneyebilirsiniz.

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

Ve, kullanmadan önce Hashtable belgelerine okuyunuz. Bu sınıf, her çağrı size ekstra koruma gerekmez zaman gerçekten erişimini yavaşlatır çoklu karşı korumalı olduğu anlamına gelir eşitlenir. Bunun yerine, HashMap veya TreeMap gibi herhangi bir Map uygulamasını kullanın.

Herkes PHP bunu yapıyoruz gibi yerine Java yapılması gerektiğini yolu, bunu yapmak için Java yol bulmaya çalışıyor gibi görünüyor. Sadece her Dizinizdeki bir nesne parçası, ya da, en azından, bir nesne olarak dizinin ilk seviye ve nesnenin içinde değişken olarak her alt seviyede düşünün. Eğer ile doldurmak yapı bir veri yapısı nesneleri dedi ve veri yapının verilen erişimcilerine aracılığıyla nesnelere erişmek.

Gibi bir şey:

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

Tabii ki bu muhtemelen doğru da değildir. Ben her sezon bir nesne yapmak, ve de bir nesne olarak belki hafta içi her gün listesi istiyorum. Her neyse, onun daha kolay, yeniden anlaşılır, ve PHP kodu taklit etmeye çalışan bir topallayarak araya Hashtable daha uzatılabilir. Tabii ki, PHP çok nesneler vardır, ve senin uber-dizileri, mümkün olan her yerine benzer bir şekilde kullanmak gerekir. Gerçi hile günaha anlıyorum. PHP çok kolay ve çok eğlenceli hale getirir!

İşte could gerisini anlamaya, benziyorsun tek yolu:

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

Ben bir Java programcısı değilim, ama sadece daha fazla dil agnostik düşünce açısından uzak Java alma ve - bunu yapmak için temizleyici bir yolu sabitleri veya numaralandırılmış türlerini ya da kullanmak için olabilir. Bu çok boyutlu diziler destekleyen herhangi langauge çalışması gerekir.

Isimli sabitler kullanıyorsanız, nerede, örneğin:

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

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

Sonra sabitleri daha okunabilir dizi simgeler olarak hizmet:

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

Numaralandırılmış türlerini kullanma:

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

@ Brian Warshaw

Bilginize, Java 1.5 ile, ilkel şimdi sarılmış sürümüne autoboxed, böylece sadece ilkel ile çağırabilirsiniz:

Hashtable<String, Integer> hash = new Hashtable<String, Integer>();
hash.put("key", 15); // Works from Java 1.5 on

Sana bazı koduna nesnelerin gobs atma gitmek için yol olduğunu düşünüyor neden olarak bir kayıp tamamen değilim. Örneğin, orada tam dört mevsim vardır ve onlar yapmak değil do veya store şey. Nasıl onları nesneler yapmak için her şeyi basitleştirmek nedir? Kanat bu muhtemelen constants (ya da belki enums) olması gerektiğini çok haklı.

Bruce o kalbinde de, ihtiyacı ne, sadece bir arama tablosudur. O nesneler ve arayüzler bir hiyerarşi gerekmez; o bir sezon ve bir grup tanımlayıcı dayalı bir program aramak için bir yol gerekir. Onlar sorumluluk veya devlet varsa nesneleri içine şeyler Torna sadece mantıklı. Onlar ne varsa, o zaman onlar sadece tanımlayıcılardır, ve onlar için özel nesneleri binanın sadece kod temeli daha büyük yapar.

Sen could, kurmak, örneğin, Group Her zamanlama dizeleri (her sezon için bir tane) bir dizi içerir, ancak tüm Group nesne yaparsa sağlamak olduğunu nesneleri arama işlevselliği, o zaman çok daha az sezgisel bir şekilde arama tablosunu yeniden icat ettik. O grubu aramak ve daha sonra program arama için varsa, o sahip olduğu tüm kod için uzun sürdü, iki aşamalı arama tablosudur arabası olması daha muhtemeldir, ve korumak için daha zor olacaktır.

@ Jason

Özellikle, neden kaynaklarda bunu sabit kodlama veya özellikleri dosyaları kullanarak yerine, bir veritabanına tüm bu verileri koymak değil mi? Bir veritabanı kullanarak korumak için çok daha kolay olacak ve seçim için ücretsiz veritabanı motorlarının çeşitli vardır olacaktır.

Bir veritabanı ekleme (kaynak doğrudan veya hatta) bir metin dosyasına kolayca sığar bir sorunu çözmek için inanılmaz ağır bir yoldur. 5 grup ve 4 mevsim vardır. Yani veritabanında 20 records toplam olacaksa olacak demektir.

@ Jason

Ben tamamen Java uygulanan ve sadece bir kavanoz dosyası da dahil olmak üzere bir uygulamada gömülebilir bağlantılı veritabanı motorlarının iki. Bu tabii, biraz ağır, ama çok daha fazla ölçeklenebilir ve korumak daha kolay. 20 kayıtlar var sırf nedeniyle bugün değişen şartlarına veya özellik sürünme daha sonra olmayacak anlamına gelmez.

Birkaç hafta veya ay içinde, diyelim ki, gün sulama kısıtlamaların süresi eklemek istediğinize karar verirseniz, o zaten bir veritabanı kullanıyorsanız bu işlevselliği eklemek çok daha kolay olacaktır. Hiç olur bile, o zaman bir uygulama, bir veritabanını nasıl embed öğrenme birkaç saat geçirdim.

Java bir DB gömülmesi, o kolay korumak için yapmaz. Daha önce yoktu ilave bir kod bağımlılık şimdi var. Bir özel araç ya kodlanmış olmalıdır veya önceki notepad.exe yeterli iken bir DB-özel arayüzü, kullanılması gerekir gibi programları kümesi güncelleniyor, şimdi daha zor. Ölçeklenebilirlik ya, burada bir endişe değil. Bu sistemin ihtiyacı bir milyon artabilir ve düz dosya hala sadece iyi çalışır.

Elbette, gelecekteki ihtiyaçlarına bir veritabanına hareketli değer noktaya gelişmeye olasıdır. Eğer değişiklik yapmak o zaman. Biz always gelecekteki ihtiyaçları hakkında yanlış varsayalım, çünkü bir uygulama işleri asla geleceğe dönük için çalışıyor. Biz tahmin programları beceremiyoruz çünkü sadece çok, ya da veritabanını gömmek için birkaç saat alacağım diyemeyiz. Hatta veritabanı uygun bir zaman gelirse, then bir veritabanını kullanmak için kod refactor. Bu arada, do the simplest thing that could {[(8 )]} work.

Ben nesneleri kapsül fonksiyonunu öne olanlar ile beraberim.

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: Ayrıca, tarih aralıkları dikkate artık yıl yapmayız:

Our seasons look like this: Summer (5-1 to 8-31) Spring (3-1 to 4-30) Fall (9-1 to 10-31) Winter (11-1 to 2-28)

import java.util.Hashtable;

public static void main(string[] args)
{
  Hashtable seasons = new Hashtable();
  Hashtable summer = new Hashtable();
  summer.put("start", *MUST_WRAP_PRIMITIVES*);
  summer.put("end", *MUST_WRAP_PRIMITIVES*);
  seasons.put("summer", summer);
}

Seni o kadar iyi hizmet etmelidir inanıyorum. Hashtables PHP (Yukarıda yazdığınız ne gibi) "ilişkisel diziler" dediği bulunmaktadır. MUST_WRAP_PRIMITIVES çizgiler ne dediğini: Sadece bir Hashtable içine çiğ tamsayı veya diğer ilkel tür sopa olamaz. Ben bir süre için Java üzerinden oldum, bu yüzden ilkel sarılması için API referans ödevlerini yapmak için size bırakacağım, ama umarım bu doğru yolda size koyacağız. İyi şanslar!

Ben kesinlikle bir temiz arayüzü arkasında bu mantık koymak gerektiğini kabul ediyorum:

public String lookupDays(String group, String date);

ama belki bir özellikler dosyasındaki verileri sopa gerekir. Ben fark gibi iç içe Koleksiyonlar gelince, Java oldukça söz olabilir, kaynak dosyaları bu verileri hardcoding karşı değilim ama. Dosyanız kudreti gibi görünüyor:

A.Summer=M
A.Spring=tTS
B.Summer=T

Genellikle bu veri ve kullandığı kod arasındaki "mesafe" artar, çünkü bir dış dosyaya bu gibi statik verileri taşımak için sevmiyorum. Eğer iç içe koleksiyonlar, özellikle haritalar ile uğraşıyoruz zaman Ancak, işler gerçek çirkin, gerçek hızlı şekilde alabilirsiniz.

Eğer bu fikri beğenmezseniz, belki de böyle bir şey yapabilirsiniz:

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

}

Bazı okunabilirliği kaybedebilir ama en azından veriler kullanılacak nereye yakın olduğunu.

Java PHP kodu uygulamak için çalışıyor durdurmak: I Ian kesinlikle doğru olduğunu düşünüyorum. Bunun yerine, bir adım geri almak ve sıfırdan bu tasarımı nasıl düşünmek. Özellikle, neden kaynaklarda bunu sabit kodlama veya özellikleri dosyaları kullanarak yerine, bir veritabanına tüm bu verileri koymak değil mi? Bir veritabanı kullanarak korumak için çok daha kolay olacak ve seçim için variety of free database motorları vardır olacaktır.

@ Derek

Bir veritabanı ekleme (kaynak doğrudan veya hatta) bir metin dosyasına kolayca sığar bir sorunu çözmek için inanılmaz ağır bir yoldur. 5 grup ve 4 mevsim vardır. Yani veritabanında 20 kayıtların toplam olacaksa olacak demektir.

Ben tamamen Java uygulanan ve sadece bir kavanoz dosyası da dahil olmak üzere bir uygulamada gömülebilir bağlantılı veritabanı motorlarının iki. Bu tabii, biraz ağır, ama çok daha fazla ölçeklenebilir ve korumak daha kolay. 20 kayıtlar var sırf nedeniyle bugün değişen şartlarına veya özellik sürünme daha sonra olmayacak anlamına gelmez.

Birkaç hafta veya ay içinde, diyelim ki, gün sulama kısıtlamaların süresi eklemek istediğinize karar verirseniz, o zaten bir veritabanı kullanıyorsanız bu işlevselliği eklemek çok daha kolay olacaktır. Hiç olur bile, o zaman bir uygulama, bir veritabanını nasıl embed öğrenme birkaç saat geçirdim.

"Tarih" bir parametre olmak zorunda mı? Sadece mevcut sulama takvimi gösteren ediyorsanız WateringSchedule sınıf kendisi ne olduğunu gün anlamaya, ve bu nedenle ne mevsim öyle. Sonra sadece Key grup harfi olan bir harita döndüren bir yöntem var. Gibi bir şey:

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

Sonra JSP sayfa

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

Eğer birden fazla sezon için programları göstermek gerekiyorsa, Mevsimler anahtarlar bir harita döndürür WateringSchedule sınıfında bir yöntem olmalıdır, ve sonra groupToScheduledDays Haritalar değerleridir.

Hayır güzel bir çözüm yoktur. Java sadece iyi böyle şeyler yapmaz. Ahmet'in çözümü hemen hemen endeksleri (anahtarlar) gibi dizeleri istiyorsanız bunu yapmak için bir yoldur. Karma-of-karmaları kurulumu çok çirkin diğer seçenek ise (utanmadan Mike çalıntı ve değiştirilmiş) birlikte dizeleri eklemek için:

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

ve sonra arama:

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

Sen (ve ben seni suçlamıyorum) genel çirkinlik memnun değilseniz, bir yöntem çağrısı geride bıraktı:

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