改变 class 的不同实例的方法调用顺序
Varying the order of method calling for different instances of a class
根据某些条件(除了以不同的顺序再次编写它们之外)处理事物完成顺序的最佳方法是什么?
假设有一个人class,Person 的每个对象代表一个不同的人。
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
}
}
如何让 satisfyNeeds()
方法根据它们的优先级调用其他三个方法?
注意:我想说清楚优先级可以因人而异。
您可以使用此代码
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(); }
}
基本上,它将优先级放在一个数组中,对数组进行排序,然后 运行 在其上使用 for 循环 运行 函数。
你应该引入一个映射属性到Person
class,其中优先方法,例如:
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);
}
...
}
并且可以用下面的方式使用:
Person Anna = new Person()
.setEatingPriority(1)
.setSleepingPriority(2)
.setWatchingTVPriority(3);
Person Bob = new Person()
.setEatingPriority(3)
.setSleepingPriority(2)
.setWatchingTVPriority(1);
Anna.satisfyNeeds();
Bob.satisfyNeeds();
您可以使用 1 个 class 和 1 个接口来完成此操作。
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();
}
}
这是另一种可能的实现方式:
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();
}
}
找到三个元素的正确顺序可以像这样简单地完成:
void satisfyNeeds() {
boolean eatFirst = eatingPriority>Math.max(sleepingPriority,recreationPriority);
if(eatFirst) eat();
if(sleepingPriority>recreationPriority) {
sleep();
watchTv();
}
else {
watchTv();
sleep();
}
if(!eatFirst) eat();
}
当然,如果你增加动作的数量,它不会缩放。要获得更高的数字,您可以查看其他答案之一。
此解决方案需要 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
void satisfyNeeds() {
needs.forEach(Runnable::run);
}
}
根据某些条件(除了以不同的顺序再次编写它们之外)处理事物完成顺序的最佳方法是什么?
假设有一个人class,Person 的每个对象代表一个不同的人。
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
}
}
如何让 satisfyNeeds()
方法根据它们的优先级调用其他三个方法?
注意:我想说清楚优先级可以因人而异。
您可以使用此代码
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(); }
}
基本上,它将优先级放在一个数组中,对数组进行排序,然后 运行 在其上使用 for 循环 运行 函数。
你应该引入一个映射属性到Person
class,其中优先方法,例如:
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);
}
...
}
并且可以用下面的方式使用:
Person Anna = new Person()
.setEatingPriority(1)
.setSleepingPriority(2)
.setWatchingTVPriority(3);
Person Bob = new Person()
.setEatingPriority(3)
.setSleepingPriority(2)
.setWatchingTVPriority(1);
Anna.satisfyNeeds();
Bob.satisfyNeeds();
您可以使用 1 个 class 和 1 个接口来完成此操作。
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();
}
}
这是另一种可能的实现方式:
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();
}
}
找到三个元素的正确顺序可以像这样简单地完成:
void satisfyNeeds() {
boolean eatFirst = eatingPriority>Math.max(sleepingPriority,recreationPriority);
if(eatFirst) eat();
if(sleepingPriority>recreationPriority) {
sleep();
watchTv();
}
else {
watchTv();
sleep();
}
if(!eatFirst) eat();
}
当然,如果你增加动作的数量,它不会缩放。要获得更高的数字,您可以查看其他答案之一。
此解决方案需要 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
void satisfyNeeds() {
needs.forEach(Runnable::run);
}
}