una tipo misma metodos metodo llamar instanciar ejemplos como clases clase atributos java methods call

java - tipo - Variando el orden de los métodos que requieren diferentes instancias de una clase



metodos arraylist java (6)

¿Cuál es la mejor manera de manipular el orden en que se hacen las cosas en función de algunas condiciones (aparte de volver a escribirlas con el orden diferente)?

Digamos que hay una clase de Persona y cada objeto de Persona representa un humano diferente.

class Person{ int eatingPriority = 3; int sleepingPriority = 2; int recreationPriority = 1; void eat() {/*eats*/} void sleep() {/*sleeps*/} void watchTv() {/*watches tv*/} void satisfyNeeds() { //HOW TO DO THIS } }

¿Cómo puedo hacer que los métodos satisfyNeeds() llamen a los otros tres métodos según su prioridad?

Nota: quiero dejar en claro que las prioridades pueden cambiar de persona a persona.


Aquí hay otra posible implementación:

abstract class Need { abstract void satisfy(); } class Eat extends Need { @Override public void satisfy() { /* eat ...*/} } class Sleep extends Need { @Override public void satisfy() { /* sleep ...*/} } class DrinkBeer extends Need { @Override public void satisfy() { /* drink beer ...*/} } class Person{ // TreeMap will sort the map in the key''s natural order (a int here) private Map<Integer, Need> needs = new TreeMap<>(); Person() { add(new Eat(), 3); add(new Sleep(), 2); add(new DrinkBeer(), 1); } void add(Need need, int priority) { needs.put(Integer.valueOf(priority), need); } void satisfyNeeds() { for(Need need : needs.values()) need.satisfy(); } }


Debe introducir una propiedad de mapa en la clase Person , donde priorizar los métodos, por ejemplo:

class Person { ... private Map<Integer, Method> methodsPriority = new HashMap<>(); ... public Person setEatingPriority(int priority) { methodsPriority.put(priority, /* put ''eat'' method reference here*/); return this; } public Person setSleepingPriority(int priority) { methodsPriority.put(priority, /* put ''sleep'' method reference here*/); return this; } public Person setWatchingTVPriority(int priority) { methodsPriority.put(priority, /* put ''watch TV'' method reference here*/); return this; } public void satisfyNeeds() { Collection<Integer> keys = methodsPriority.keySet(); Collections.sort(keys); for(Integer key: keys) methodsPriority.get(key).invoke(this); } ... }

Y se puede utilizar de la siguiente manera:

Person Anna = new Person() .setEatingPriority(1) .setSleepingPriority(2) .setWatchingTVPriority(3); Person Bob = new Person() .setEatingPriority(3) .setSleepingPriority(2) .setWatchingTVPriority(1); Anna.satisfyNeeds(); Bob.satisfyNeeds();


Encontrar el orden correcto de tres elementos se puede hacer simplemente así:

void satisfyNeeds() { boolean eatFirst = eatingPriority>Math.max(sleepingPriority,recreationPriority); if(eatFirst) eat(); if(sleepingPriority>recreationPriority) { sleep(); watchTv(); } else { watchTv(); sleep(); } if(!eatFirst) eat(); }

Por supuesto, no se escalará si aumenta el número de acciones. Para un número más alto puede mirar una de las otras respuestas.


Esta solución requeriría Java 8:

class Person { void eat() {}; void sleep() {}; void watchTv() {}; // Being in a List you can easily reorder the needs when you want to List<Runnable> needs = Arrays.asList(this::eat, this::sleep); // Alternatively, you can use a Map<Runnable, Integer> where the value is your // priority and sort it (see http://.com/q/109383/1296402) void satisfyNeeds() { needs.forEach(r -> r.run()); } }


Puedes hacer esto con 1 clase y 1 interfaz.

public class Person { int eatingPriority = 3; int sleepingPriority = 2; int recreationPriority = 1; PriorityQueue<Action> actions; void eat() { } void sleep() { } void watchTv() { } public Person() { actions = new PriorityQueue<Action>(new Comparator<Action>() { @Override public int compare(Action o1, Action o2) { return o2.getPriority() - o1.getPriority(); } }); actions.add(new Action() { @Override public int getPriority() { return eatingPriority; } @Override public void execute() { eat(); } }); actions.add(new Action() { @Override public int getPriority() { return sleepingPriority; } @Override public void execute() { sleep(); } }); actions.add(new Action() { @Override public int getPriority() { return recreationPriority; } @Override public void execute() { watchTv(); } }); } public void satisfyNeeds() { for (Action action : actions) { action.execute(); } } interface Action { public int getPriority(); public void execute(); } }


Puedes usar este código

import java.util.Arrays; // must be imported int[] priorities = {sleepPriority, eatPriority, recreationPriority}; Arrays.sort(priorities); for (int i=priorities.length-1; 0<=i; i--) { int priority = priorities[i]; if (priority == sleepingPriority) { sleep(); } if (priority == eatingPriority) { eat(); } if (priority == recreationPriority) { watchTv(); } }

Básicamente, coloca las prioridades en una matriz, la ordena y ejecuta un bucle for en ella para ejecutar las funciones.