Sposób na referencję do metody

0

Witam,
piszę sobie prostą aplikację w której użytkownik wybiera w Combo Box jakieś równanie arytmetyczne. Każde z tych równań ma odpowiadającą sobie metodę wyliczającą wartość tego równania. Pobieram String reprezentujący wybraną opcję i za pomocą warunków wywołuję odpowiednią funkcję. Niestety wywoływanie tej funkcji jest w pętli przez co ten sam warunek może być sprawdzany bezsensownie kilkanaście razy.

I tutaj pojawia się moje pytanie czy w Javie jest jakiś sposób aby przypisać referencję do metody, coś jak delegaty w C#?
W ten sposób po wyborze równania w Combo Boxie referencji przypisałbym odpowiednią metodę i musiałbym tylko tą delegatę wywoływać w pętli, bez ciągłego sprawdzania warunku.

Poniżej część kodu mojego programu:

public void setFunctionName(String functionName){
        this.functionName = functionName;
    }
public double calculateFunction(double x){
        if( functionName.equals("x^2+2x"))
            return Function1(x);
        else if( functionName.equals("sin(x)"))
            return Function2(x);
        else if( functionName.equals("x^2+5x"))
            return Function3(x);
        else if( functionName.equals("3x^3+2"))
            return Function4(x);
        else if( functionName.equals("10x+2"))
            return Function5(x);
        else
            return 0;
    }
public void calculateResult(){
        result = 0;
        for( int i = 0; i <= degree; i++ )
            result += polynomials.get(i)*calculateFunction(nodes.get(i));
    }
 

z góry dziękuję za pomoc :)

0

Możesz od biedy zrobić hierarchię klas implementującą interfejs ArithmeticOperation który będzie miał metodę compute(double x). W zależności od działania będziesz tworzył sobie odpowiednie obiekty.

0

To sie robi tak jak pisze shalom - tworzysz interfejsy (BinaryOperation, UnaryOperation) i implementujesz (Constant (unary), Variable (unary), UnaryMinus, Minus, Plus, Mul i inne), a nastepnie taki input ("x * y + 2") parsujesz w drzewo dzialan. W tym przykladzie:

                          Plus
              Mul                     Constant(2)

Variable(x) Variable(y)

  1. teraz, wolasz na roocie Plus.evaluate(), a on wola:
  2. left.evaluate() + right.evaluate() (czyli mu.evaluate() + constant.evaluate()
  3. mul.evaluate() wola:
    left.evaluate() * right.evaluate() (czyli var(x) * var(y))
    4. a.a left.evaluate() (var(x))zwraca wartosc x
    5. a.b right evaluate (var(y)) zwraca wartosc y
    czyli mul.evaluate() zwrca wartosc mnozenia
  4. constant.evaluate() zwraca 2
  5. ostatecznie, plus.evaluate() zwraca wartosc mnozenia + constant

Parsowanie dzialan na takie drzewko robisz np za pomoca ONP.

0

@mućka, raczej pieprzysz nie na temat.
Ja bym użył refleksji i HashMapy metody, która wiąże napisy z metodami.
A potem

return metody.get(functionName).invoke(this,x);
0

Zauwaz jakie sa te jego 'metody'. To sa zlozone dzialania. Co, bedziesz w mapie trzymal x2, x3, x4, 2x2, 2x*3, itp? Jesli tak to gratulacje - ta mapa bedzie calkiem spora, wlasciwie to ona bedzie nieskonczenie wielka. Ja bym raczej napisal to inaczej.

0

W tym combo moga byc rozne dzialania, i wiele ich. Mozna zrobic jakas proteze jaka proponujecie, albo porzadnie. Ponadto, ComboBox pozwala na wybor z listy predefiniowanych zadan, ale rowniez na wpisanie wlasnego (jesli aplikacja pozwala, dlatego 'combo'). W tej sytuacji juz nie ma innego rozwiazania.
Dziwi mnie ze nie wiecie podstaw jak sie robi takie zadania, szczegolnie wibowit ktory jest 'akademikiem' ;d Sprobujcie podac Wasze rozwiazanie z sztywno wpisanymi funkcjami na jakiejs rozmowe kwalifikacyjnej ;d

0

Dziwi mnie ze nie wiecie podstaw jak sie robi takie zadania, szczegolnie wibowit ktory jest 'akademikiem' ;d

Nie wiem skąd ta aluzja, bo nie udzielałem się jeszcze w tym wątku.

Sprobujcie podac Wasze rozwiazanie z sztywno wpisanymi funkcjami na jakiejs rozmowe kwalifikacyjnej ;d

A tu nie chodzi przypadkiem o to, żeby funkcje były sztywne? :] Wtedy zrobiłbym interfejsy FunkcjaUnarna, FunkcjaBinarna każdy z jedną metodą i trzymał ich implementacje skojarzone ze Stringami w HashMapie. Podobnie jak bogdans.
Edit:
W sumie podane funkcje przyjmują zawsze jeden parametr, z tego co widzę, więc wystarczyłby jeden interfejs.

Ogólnie podałeś dobre rozwiązanie, ale być może zbyt skomplikowane. Na pewno do ONP nie jest wymagane tworzenie AST. AST przydają się przy dzieleniu, łączeniu, optymalizowaniu, itd funkcji, ale do samego obliczania wystarczy sam stos operandów i operacji.

0

Sory, pomylilem bogdansa z Toba. My bad.

0

Dziękuję za tak liczne odpowiedzi. Tak jak stwierdził wibowit, Combo Box z założenia ma mieć trybie edytowania wyłączony i będzie do wyboru tylko kilka "sztywnych" funkcji. I wszystko rozchodziło się o to, żeby uniknąć ciągłego sprawdzania w pętli "calculateResult" która funkcja jest wybrana. Przetestuję sobie wkrótce kod z użyciem interfejsów.

Jednak wypowiedź mućka zachęciła mnie, żeby sobie w wolnym czasie spróbować zmodyfikować kod i dodać możliwość wpisywania własnych funkcji do combo boxa ;)

Dzięki wielkie!

0

Możliwe jest jeszcze inne podejście, niestety wymaga komputera z JDK. Napisałem kiedyś dwa programy, które rysują wykres dowolnej funkcji wpisanej przez użytkownika i trajektorię dowolnego systemu dynamicznego wpisanego przez użykownika, działają tak: tworzony jest plik z klasą implementującą odpowiedni interfejs, klasa jest kompilowana, tworzony jest obiekt tej klasy i używana jest metoda tego obiektu.

0

Nie trzeba JDK, wystarczy dowolny kompilator Javy czy innego języka do bajtkodu.

0

A mnie zastanawia czy nie pościej jest dodawać do comboboxa funkcji jako takich?

	public static void main(String[] a) {
		JFrame jf = new JFrame("aaaa");
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		final JComboBox jcb = new JComboBox();
		jf.add(jcb, BorderLayout.CENTER);

		jcb.addItem(new F1());
		jcb.addItem(new F2());

		JButton jb = new JButton("Wynik");
		jb.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseClicked(MouseEvent e) {
				System.out.println(((F) jcb.getSelectedItem()).result());
			}
		});
		jf.add(jb, BorderLayout.NORTH);
		jf.setSize(300, 300);
		jf.setVisible(true);
	}

Oczywiście tu w dużym uproszczeniu, bo można sobie zbudować komponent rozszerzający CB i działający jako widok funkcji. W takim przypadku przycisk pobiera z widoku aktualny stan (funkcję) i ją po prostu wykonuje.

0

Gdzies to mapowanie stringa to obiektu musi miec miejsce, nie w kombo boksie to gdzies wczesniej - od tego nie uciekniesz.

0

Mapowanie polega na dodaniu funkcji bezpośrednio do CB, a klasa implementująca interfejs Function dodatkowo przesłania toString(). CB wyświetla wartość zwróconą przez toString, ale jak dasz getSelectedItem to zwróci obiekt który był dodany.

0

Tak, rozumiem. Ale gdzies musi byc mapowanie ktore ze stringow tworzy obiekty F1 czy tam F2. Moze to byc shardkodowane, a moze nie.

0

Hm.. przykładowa implementacja Function:

interface Function {

	double compute(double param);

}

class LinearFunction implements Function {

	@Override
	public double compute(double param) {
		return param;
	}

	@Override
	public String toString() {
		return "x";
	}

}

kolejne funkcje można dodawać za pomocą Własne usługi w JSE wtedy nie trzeba nawet się wysilać na łączenie widoku - CB z konkretnymi funkcjami tylko po drodze dać FunctionStorage, który będzie zwracał listę dostępnych funkcji.

0

Trochę dziwne, ale jak pisałem ten swój program do rysowania wykresów, to użyłem interfejsu:

interface Function {
        double compute(double param);
}
0

@koziolek: no wlasnie twoje Funkcje sa na sztywno zdefiniowane (wnioskuje z Twojej metody toString()), podczas gdy mi chodzilo o to ze np. wczytujesz stringa skad, np. z pliku, i musisz z niego zrobic Funkcje. To czy robisz to wczesniej, i kombo uzywa Funkcji, czy kombo uzywa stringow, a lookup jest po wyborze usera, to jedno i to samo, tylk ojedno wczesniej drugie pozneij. W tej sytuacji oczywiscie masz racje ze mozna tak zrobic, ale rozszerzalne to to nie jest i nie bedzie.

0

No to można klasycznie potraktować input jako fragment kodu i następnie ASMem pojechać: http://asm.ow2.org/

1 użytkowników online, w tym zalogowanych: 0, gości: 1