Permalänk
Medlem

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.

Permalänk
Hedersmedlem

Vill du inte hellre lösa det med interface?

Permalänk
Medlem

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.

Permalänk
Medlem

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

Permalänk
Hedersmedlem
Permalänk
Medlem

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

Permalänk
Medlem

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

Visa signatur

Kom-pa-TI-bilitet

Permalänk

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.

Permalänk
Medlem

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?

Permalänk
Medlem

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

Permalänk
Medlem
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.

Permalänk
Medlem

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

Permalänk
Medlem
Permalänk
Medlem
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.

Permalänk

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

Visa signatur

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

Permalänk
Medlem
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!).

Permalänk
Medlem
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.