mboost-dp1

Java: Loope gennem ukendte fields i objekter


Gå til bund
Gravatar #1 - nielsbuus
4. nov. 2011 08:43
Hej Newz

Kan man lave en metode som tager imod en collection af objekter og gennemsøger deres fields for en arbitrær streng og returnerer en collection med de objekter hvis fields indeholder indeholder denne streng?

Eller mere konkret:
Lad os sige at jeg har et personobjekt som består af 3 strings, et firstName, et lastName og en mailAddress. I de loops jeg hidtil har lavet til at gennemsøge med, der bruger jeg String metoden equals på alle 3 felter, for at se om en søgning returnerer et hit. Men det kræver at jeg koder felternes nævne ind i søgemetoden og så virker den således kun for den konkrete objektklasse.

Kan man generalisere den så den undersøger de String fields der måtte være i et given objekt eller kører toString på samtlige fields og herefter undersøger disse?

Thants.
Gravatar #2 - hundeboll
4. nov. 2011 10:41
#1 MadiZone:
Kan du ikke lave en metode i personobjektet, som søger i sine egne felter og returnerer true, hvis der er et hit?

Altså noget i stil med:

class Person ()
{
string forNavn;
string efterNavn;
string mailAddress;

public bool strSearch(string needle)
{
if (forNavn.equals(needle))
return true;

if (efterNavn.equals(needle))
return true;

if (mailAddress.equals(needle))
return true;

return false;
}
}


(Det er nok 3 år siden jeg prøvede Java og der skrev jeg kun 10 linjer :p)
Gravatar #3 - arne_v
4. nov. 2011 12:36
#1

Du kan godt finde alle fields af typen string i et vilkårligt objekt via reflection.

Det koster lidt CPU på runtime, men det virker.
Gravatar #4 - arne_v
4. nov. 2011 12:47
#3

Eksempel:


import java.lang.reflect.Field;

public class ReflDemo {
public static void dump(Object o) throws IllegalArgumentException, IllegalAccessException {
for(Field f : o.getClass().getDeclaredFields()) {
f.setAccessible(true);
System.out.println(f.getType().getName() + " : " + f.get(o));
}
}
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
dump(new C1(123, "ABC"));
dump(new C2(123.456, "XYZ"));
}
}

class C1 {
private int iv;
private String sv;
public C1(int iv, String sv) {
this.iv = iv;
this.sv = sv;
}
public int getIv() {
return iv;
}
public String getSv() {
return sv;
}
}

class C2 {
private double xv;
private String sv;
public C2(double xv, String sv) {
this.xv = xv;
this.sv = sv;
}
public double getXv() {
return xv;
}
public String getSv() {
return sv;
}
}
Gravatar #5 - myplacedk
4. nov. 2011 20:33
Hvad arne_v sagde. Og:

Det du ønsker at gøre, kan kun gøres med reflection. Men min påstand er, at når reflection er den eneste løsning, har man nok gjort noget forkert.

Hvis jeg skal give et brugbart råd (fx. hvad du skal gøre i stedet for) skal jeg høre mere om hvorfor du vil gøre det,du spørger om hjælp til.
Gravatar #6 - myplacedk
4. nov. 2011 20:38
Jeg kom lige i tanker om...

Det du siger minder mig egentlig om noget jeg har set mange gange før. Måske kan dette bruges:

Alle objekter som du vil undersøge, skal implementere et interface, fx. "PropertyContainer". Dette interface indeholder noget i stil med:

public List<String> getProperties(); // Giver en liste over property-navne
public String getProperty(String property); // Giver værdien af den navngivne property


Eller måske helt simpelt:

public Map<String, String> getProperties();
Gravatar #7 - arne_v
6. nov. 2011 03:00
#5

De fleste avancerede Java frameworks bruger reflection fordi det giver en utrolig fleksibilitet.

Men det er et værktøj som kun skal bruges når det er nødvendigt.

Man bruger heller ikke 210 mm haubitser til at slå en flue ihjeld med - en fluesmækker er nok. Til gengæld duer en fluesmækker ikke rigtigt til at eliminere en beton bunker med.
Gravatar #8 - myplacedk
6. nov. 2011 08:33
arne_v (7) skrev:
De fleste avancerede Java frameworks bruger reflection fordi det giver en utrolig fleksibilitet.

...hvilket er en del af min pointe. Langt de fleste laver ikke avancerede frameworks. Og dem som gør, spørger ikke om hjælp på den måde. :)
Gravatar #9 - arne_v
6. nov. 2011 19:25
#8

Forhåbentligt ikke.

Men dem som skal lave reflection i et eller andet avanceret framework skal jo også lære det ved at starte med reflections "hello world".
Gravatar #10 - Arnfast
7. nov. 2011 04:41
Ofte når jeg går i refleksion mode, ender jeg tit ud i at bruge visitor pattern: http://en.wikipedia.org/wiki/Visitor_pattern

Afhængig af præcis af hvad du skal bruge funktionen til, får man ofte en meget smuk afkobling ved at bruge det
Gravatar #11 - nielsbuus
8. nov. 2011 23:01
Hej Arne V og andre.

Tak for forslagene. Jeg vil eksperimentere med dem. :-)
Jeg kan ikke helt gennemskue koden, men det kommer nok efterhånden som jeg får studeret den.

Til hundeboll:

Dit forslag er interessent og lige til - men kræver dog at man selv implementerer en søgefunktion i hver klasse. Jeg tænker på noget logik som kører toString på alle fields i et objekt og søger i det.
Gå til top

Opret dig som bruger i dag

Det er gratis, og du binder dig ikke til noget.

Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.

Opret Bruger Login