java: skicka metod som parameter

Trädvy Permalänk
Medlem
Plats
Lund
Registrerad
Maj 2006

java: skicka metod som parameter

Hejsan.

Undrar om man kan skicka en medtod som parameter med en annan metod.

Ex.

Public class user() {
Public string getFnamn() { return fnamn; }
Public string getEnamn() { return enamn; }
}

Public class main() {

Public string metod(User aUser, Method method) {
Return auser.method;
}

String name = metod(new user(kalle), User.getFnamn());

}

Typ så och då blir name kalle.

Trädvy Permalänk
Hedersmedlem
Plats
Linköping
Registrerad
Apr 2004

Vill du inte hellre lösa det med interface?

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Feb 2003

Som Elgot skriver gör du det enklast med ett interface.
Om du bestämt måste göra något i stil med det du visar kan du säkert lösa det med hjälp av reflection.

Trädvy Permalänk
Medlem
Plats
Lund
Registrerad
Maj 2006

hur gör man med interface/reflection?

jag löste det själv på detta sätt.

String theMethod = "getTel"; public int myMethod(Object obj) { int result = 0; Object object = null; if (obj instanceof package.MyClass) { object = (MyClass) obj; } try { Method myMethod = object.getClass().getMethod(theMethod, null); try { int res = (Integer)myMethod.invoke(obj, null); result = res; } catch(IllegalArgumentException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } } catch (NoSuchMethodException e) { } return result; }

Trädvy Permalänk
Hedersmedlem
Plats
Linköping
Registrerad
Apr 2004
Trädvy Permalänk
Medlem
Plats
Lund
Registrerad
Maj 2006

Tack Elgot.

Som jag förstår det kan jag nog inte lösa det med interface. Metoden jag vill anropa kan vara olika beroende på vilken klass objektet tillhör som skickas med.

Det jag vill göra är att sortera olika objekt där objektet kan sorteras på olika sätt.
Objekten kan ex. vara instanser av klassen User, House, Animal, CarMaker. User kan sorteras på ex. efternamn men det går inte med Animal då denna inte har nått efternamn. Animal vill jag kanske istället sortera på ras eller vikt.

Anledningen till att jag vill göra så här är för att jag har data i olika tabeller som ska sorteras stigande eller fallande med hjälp av en sorterings-metod som är så generell som möjligt

Går det med interface får ni gärna berätta hur med nått exempel. Nu funkar det som jag vill men går det att förbättra lyssnar jag

så här ser min sorteringsklass ut nu (med vissa modifieringar)

//Sortera List<Users> userList = getAllUsers(); Collections.sort(userList, new mySorter("getUsername"));

package myPackage; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Comparator; public class mySorter implements Comparator { private String method; public mySorter(String method) { this.method = method; } public int compare(Object obj1, Object obj2) { int result = 0; Object object1 = null; Object object2 = null; if (obj1 instanceof myPackage.User) { object1 = (User) obj1; object2 = (User) obj2; } else if (obj1 instanceof myPackage.House) { object1 = (House) obj1; object2 = (House) obj2; } else if (obj1 instanceof myPackage.Animal) { object1 = (Animal) obj1; object2 = (Animal) obj2; } if (object1 != null) { try { Method myMethod1 = object1.getClass().getMethod(method); Method myMethod2 = object2.getClass().getMethod(method); try { String res1 = myMethod1.invoke(obj1) + ""; String res2 = myMethod2.invoke(obj2) + ""; result = res1.compareTo(res2); } catch(IllegalArgumentException e) { //log error } catch (IllegalAccessException e) { //log error } catch (InvocationTargetException e) { //log error } } catch (NoSuchMethodException e) { //log error } } else { //log error } return result; } }

Trädvy Permalänk
Medlem
Plats
i din garderob
Registrerad
Sep 2007

Genom att programmera sådär knyter du dig till de klasser som redan finns. Skulle du skapa en ny klass kommer du behöva lägga till den i if-testen. Vad du istället kan göra är att skapa interface Sorterbar (namn godtyckligt) som du sedan implementerar i de klasser som ska kunna sorteras. Något sånt här..

interface Sorterbar { public String getSortString(); } ... class User implements Sorterbar { ... public String getSortString() { return username; } } // din compare-metod: public int compare(Sorterbar s1, Sorterbar s2) { int result; String first; String second; first = s1.getSortString(); second = s2.getSortString(); result = first.compareTo(second); return result; }

edit: fast vad du verkligen verkar vilja göra är att implementera interface Comparable, så att du kan köra en compareTo direkt på dina klasser

Bilanaloger är som Volvo — varenda svenne kör med dem

Trädvy Permalänk
Medlem
Plats
Laholm
Registrerad
Okt 2005

Finns inte dessa klasser redan i Java-ramverket?

Men titta här...

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Comparable....

class Person implements Comparable { private String firstname; private String lastname; public String Firstname() { return firstname; } public String Firstname(String newFirstname) { firstname = newFirstname; return firstname; } public String Lastname() { return lastname; } public String Lastname(String newLastname) { lastname = newLastname; return lastname; } public int compareTo(Object o) { return lastname.compareTo(((Person)o).Lastname()); } }

Borde göra Person-instanser sorterbara på efternamnet.

ASP.NET programmerare i C#
Twitter: http://www.twitter.com/hagbarddenstore

Trädvy Permalänk
Medlem
Plats
Lund
Registrerad
Maj 2006

Tack för förklaringen Teknocide, men om jag av någon anledning vill sortera på något annat än en String går det väl inte?

Låt oss säga att User har
String fnamn, enamn;
int tel;

Hur sorterar jag på de olika typerna isf?

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Feb 2003

Alla klass du vill kunna sortera implementerar interfaces Comparable, därefter skriver du jämförelsekoden i respektive klass (i stil med det hagbarddenstore skrivit) som du sedan kan anropa. Enklare än så är det inte.

public class User implements Comparable { public int compareTo(Object o) { return this.firstName.compareTo(((User) o).firstName); } } public class House implements Comparable { public int compareTo(Object o) { return this.address.compareTo(((House) o).address); } } public class Animal implements Comparable { public int compareTo(Object o) { return this.name.compareTo(((Animal) o).name); } } public class CarMaker implements Comparable { public int compareTo(Object o) { return this.name.compareTo(((CarMaker) o).name); } }

Trädvy Permalänk
Medlem
Plats
Lund
Registrerad
Maj 2006
Citat:

Ursprungligen inskrivet av Garret
Alla klass du vill kunna sortera implementerar interfaces Comparable, därefter skriver du jämförelsekoden i respektive klass (i stil med det hagbarddenstore skrivit) som du sedan kan anropa. Enklare än så är det inte.

public class User implements Comparable { public int compareTo(Object o) { return this.firstName.compareTo(((User) o).firstName); } } public class House implements Comparable { public int compareTo(Object o) { return this.address.compareTo(((House) o).address); } } public class Animal implements Comparable { public int compareTo(Object o) { return this.name.compareTo(((Animal) o).name); } } public class CarMaker implements Comparable { public int compareTo(Object o) { return this.name.compareTo(((CarMaker) o).name); } }

och hur gör jag om jag vill mer än en string i samma klass? Som jag skrev ovan kan ex. User ha ett telefonnummer som jag vill göra jämförelsen med också. Tex först sortera på namn och sen på telefonnummer.

Trädvy Permalänk
Medlem
Plats
Göteborg
Registrerad
Maj 2007

Utöka dina compareTo-metoder bara, då metoden compareTo() returnerar ett relations-heltal som är 0 om dom är lika;

public class User implements Comparable { public int compareTo (Object o) { if (this.name.compareTo(((User) o).name) == 0) { return this.phonenumber.compareTo(((User) o).phonenumber); } return this.name.compareTo(((User) o).name); } }

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Okt 2004

Exempel på Comparable och Comparator i Java.

http://devpinoy.org/blogs/lamia/archive/2007/04/16/java-util-...

Trädvy Permalänk
Medlem
Plats
Lund
Registrerad
Maj 2006
Citat:

Ursprungligen inskrivet av bjornie
Utöka dina compareTo-metoder bara, då metoden compareTo() returnerar ett relations-heltal som är 0 om dom är lika;

public class User implements Comparable { public int compareTo (Object o) { if (this.name.compareTo(((User) o).name) == 0) { return this.phonenumber.compareTo(((User) o).phonenumber); } return this.name.compareTo(((User) o).name); } }

Jag var lite otydlig. Jag menade att ibland vill jag sortera på namn och ibland på telefonnummer.

@Racy
Med den lösningen måste jag skapa en klass för varje variabel som jag vill sortera på, det blir för meckigt att göra så med alla varianter jag har.

Trädvy Permalänk
Medlem
Plats
Bromma
Registrerad
Aug 2008

Kan du inte bara skicka med typen du vill jämföra med in till compareto-funktionen?

Asus Striker II Extreme / XFX Geforce GTX 280 / Q9450 @ 3.6GHz/ TRUE Noctua 120/ 4x1GB Corsair TWIN3X2048-1333C9DHX / X25-M G2 80gb Velociraptor / Win 7 Ultimate x64/ Antec P190

MovieDatabase

Trädvy Permalänk
Medlem
Plats
Göteborg
Registrerad
Maj 2007
Citat:

Jag var lite otydlig. Jag menade att ibland vill jag sortera på namn och ibland på telefonnummer.

Ja, du får tala ur skägget för att man ska förstå

Det finns i så fall en Comparator-klass (obs! Comparator != Comparable) du kan använda på ett par olika sätt. Se följande exempel som jag postade på ett annat forum för flera månader sedan (copy&paste):

/*Användning av inre klasser:*/ package bjorn.app; import java.util.Comparator; import java.util.PriorityQueue; public class QueueUsage { public static void main(String[] args) { Comparator<Shoe> comparator = new ShoeColorComparator(); PriorityQueue<Shoe> queue = new PriorityQueue<Shoe>(5, comparator); queue.add(new Shoe("Blå", 42)); queue.add(new Shoe("Röd", 41)); queue.add(new Shoe("Grön", 34)); while (queue.size() != 0) { Shoe current = queue.remove(); System.out.println("Storlek: " + current.getSize()); System.out.println("Färg: " + current.getColor() + "\n"); } } static class ShoeSizeComparator implements Comparator<Shoe> { public int compare(Shoe x, Shoe y) { if (x.getSize() > y.getSize()) return 1; if (x.getSize() < y.getSize()) return -1; return 0; } } static class ShoeColorComparator implements Comparator<Shoe> { public int compare(Shoe x, Shoe y) { if (x.getColor().charAt(0) > y.getColor().charAt(0)) return 1; if (x.getColor().charAt(0) < y.getColor().charAt(0)) return -1; return 0; } } } /*------------------------*/ /* 2. Alternativt användning av anonyma klasser: */ /*------------------------*/ package bjorn.app; import java.util.Comparator; import java.util.PriorityQueue; public class QueueUsage { public static void main(String[] args) { Comparator<Shoe> comparator = new Comparator<Shoe>() { public int compare(Shoe x, Shoe y) { if (x.getSize() > y.getSize()) return 1; if (x.getSize() < y.getSize()) return -1; return 0; } }; PriorityQueue<Shoe> queue = new PriorityQueue<Shoe>(5, comparator); queue.add(new Shoe("Blå", 42)); queue.add(new Shoe("Röd", 41)); queue.add(new Shoe("Grön", 34)); while (queue.size() != 0) { Shoe current = queue.remove(); System.out.println("Storlek: " + current.getSize()); System.out.println("Färg: " + current.getColor() + "\n"); } } }

Comparator bör användas när det inte finns någon naturlig sortering för ett objekt, som t.ex. en Sko-klass som ovan. Har man istället ett objekt som har en naturlig sortering (en Längd-klass, t.ex.) så bör man istället implementera Comparable. Alternativ ett är antagligen vad som skulle passa dig bäst, eftersom att inte Closures finns med i Java (ännu hoppas vi!).

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Okt 2004
Citat:

Ursprungligen inskrivet av stantemo
Jag var lite otydlig. Jag menade att ibland vill jag sortera på namn och ibland på telefonnummer.

@Racy
Med den lösningen måste jag skapa en klass för varje variabel som jag vill sortera på, det blir för meckigt att göra så med alla varianter jag har.

Det behöver du väl inte. Du kan ju göra en "comparator-klass" där du väljer vilken typ av sortering du vill ha i t.ex konstruktorn och sedan anpassa compare metoden därefter. Då behöver du inte duplicera kod.