我遇到了一个问题,我不允许使用switch / case或if / else查询。
我收到了一个我读过的配置文件:
650;0;1.5;month
614;0;2.88;year
466;0;2.48;week
716;0;4.6;half-year
718;0;2.6;quarter
我将这些字符串拆分为“;”,因此将其保存在数组中。我遇到的问题是,我需要在代码中为代码中的其他内容执行其他操作ar [3],所以如果是一个月我还需要其他计算,那么当它是一整年时。
但我不允许用Switch / case或If / Else这样做,现在我感到困惑。
If (ar[3] = month){
do this;
else if (ar[3] = year) {
do this;
}
我如何做这个面向对象的?感谢您的帮助:)
答案 0 :(得分:2)
根据ar [3]中的时间段,您似乎需要某种继承结构。可以为每种情况编码特殊的do this
方法。这样你就能够为每种情况做一些不同的事情。您只需要一种方法来首先实例化正确的子类型。有很多方法可以解决这个问题。
最直接的方法是恕我直言,条件算子?:
。
所以代码看起来像这样:
MyClass x = ar[3].equals("month") ? new MyClassMonth() :
(ar[3].equals("year") ? new MyClassYear() :
(ar[3].equals("week") ? new MyClassWeek() :
(ar[3].equals("half-year") ? new MyClassHalfyear() :
new MyClassQuarter())));
x.doSomething();
嵌套的条件表达式使您能够选择正确的类,继承为您提供所需的多态行为。
但您在评论中提到您也无法使用?:
。下一步是什么?
假设您编写了MyClassMonth
,其中任何内容都不依赖于任何记忆状态,即doSomething()
方法没有副作用。然后你可以创建一个Map<String, MyClass>
来存储每个子类的一个实例,然后在你需要调用时将相关的一个拉出地图。
您可以像这样初始化地图:
final Map<String, MyClass> themap = new HashMap<>();
{
themap.add("month", new MyClassMonth());
themap.add("year", new MyClassYear());
themap.add("week", new MyClassWeek());
themap.add("half-year", new MyClassHalfyear());
themap.add("quarter", new MyClassQuarter());
}
以doSomething()
作为参数调用ar
:
MyClass x = themap.get(ar[3]);
if (x != null)
x.doSomething(ar);
还有其他方法可以做到这一点。坚持使用Map
概念,您可以将类文字存储在Map
而不是实例中,然后反复实例化它们。你也可以在Map
中保留一个lambda并调用它。
@OldCurmudgeon建议使用枚举。如果你将这些枚举放入Map
并将一个lambda添加到枚举中,你可以获取枚举并调用lambda。这可行,并具有一定的吸引力,但似乎没有必要。你最好直接调用lambda。
答案 1 :(得分:2)
您可以使用 profile.setPreference("browser.download.folderList",2)
profile.setPreference("browser.download.manager.showWhenStarting",false)
profile.setPreference("browser.download.dir", new File("").getAbsolutePath())
profile.setPreference("browser.helperApps.neverAsk.saveToDisk","application/zip")
作为命令工厂模式,并使用enum
查找实现选择。
Map
正确打印:
// Lookups for teh period.
static final Map<String, Period> lookup = new HashMap<>();
enum Period {
Month("month") {
@Override
void process(int x, int y, double v) {
// Processing for "month" records here.
System.out.println(this + "-process(" + x + "," + y + "," + v + ")");
}
},
Year("year") {
@Override
void process(int x, int y, double v) {
// Processing for "year" records here.
System.out.println(this + "-process(" + x + "," + y + "," + v + ")");
}
},
Quarter("quarter") {
@Override
void process(int x, int y, double v) {
// Processing for "quarter" records here.
System.out.println(this + "-process(" + x + "," + y + "," + v + ")");
}
},
HalfYear("half-year") {
@Override
void process(int x, int y, double v) {
// Processing for "half-year" records here.
System.out.println(this + "-process(" + x + "," + y + "," + v + ")");
}
};
Period(String inData) {
// Record me in the map.
lookup.put(inData, this);
}
abstract void process(int x, int y, double v);
static void process(String data) {
String[] parts = data.split(";");
Period p = lookup.get(parts[3]);
if (p != null) {
p.process(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), Double.parseDouble(parts[2]));
}
}
}
public void test() {
String[] test = {"650;0;1.5;month",
"614;0;2.88;year",
"466;0;2.48;week",
"716;0;4.6;half-year",
"718;0;2.6;quarter",};
for (String s : test) {
Period.process(s);
}
}
请注意,其中只有一个Month-process(650,0,1.5)
Year-process(614,0,2.88)
HalfYear-process(716,0,4.6)
Quarter-process(718,0,2.6)
,但这只是防御以避免错误数据 - 它不是查找机制的一部分。
答案 2 :(得分:1)
这样的事情:
public interface Calculator {
double calculate(int p1, int p2, double p3);
}
public class YearCalculator implements Calculator {
public double calculate(int p1, int p2, double p3) {
double value = 0.0;
// do year calculations
return value;
}
}
public class CalculatorFactory {
public Calculator getInstance(String type) {
Calculator calculator = null;
if (type != null) {
} else {
throw new IllegalArgumentException("calculator type cannot be null");
if ("year".equalsIgnoreCase(type)) {
} else {
System.out.println(String.format("No such type: %s", type));
}
}
return calculator;
}
}
您必须在工厂中使用if / else逻辑,但在解析文本时则不行。
您的处理代码:
CalculatorFactory factory = new CalculatorFactory();
// contents is a List of Strings from your input file.
for (String line : contents) {
String [] tokens = line.split(";");
Calculator calculator = factory.getInstance(tokens[3]);
double value = calculator.calculate(Integer.parseInt(tokens[0]), Integer.parseInt(tokens[1]), Double.parseDouble(tokens[2]));
}
答案 3 :(得分:0)
基于Codebender作为替代解决方案的建议:
您需要5个类,每个案例一个,具有通用接口但实现方式不同。
您的界面可能如下所示:
public interface MyCalculator {
public double calculate(double a, double b, double c);
}
然后你需要实现与此类似的5个类。对于calculate
,month
,year
,week
和half-year
,您需要针对quarter
的不同实现使用不同的类:
public class MyMonthCalculator implements MyCalculator {
@Override
public double calculate(double a, double b, double c) {
// Do your calculations here then return
}
}
然后,在解析逻辑之前,您可以将五个类添加到Map
。
map.put("month", new MyMonthCalculator());
// Repeat for year, week, half-year and quarter
要实际执行计算:
double result = map.get(ar[3]).calculate(Double.parseDouble(ar[0]), Double.parseDouble(ar[1]), Double.parseDouble(ar[2]));
答案 4 :(得分:0)
您可以使用选项数组模拟if
或case
。这里唯一的问题是在这样的数组中找到我们元素的索引。我们无法使用if
和case
,但我认为while
是一种选择。
所以你的代码可能类似于:
String[] options = { "foo", "bar", "baz" };
Runnable[] action = { new Runnable() {
@Override
public void run() {
System.out.println("handling foo");
}
}, new Runnable() {
@Override
public void run() {
System.out.println("handling bar");
}
}, new Runnable() {
@Override
public void run() {
System.out.println("handling baz");
}
} };
String choice = "bar";
int matched = 0;
int i = -1;
while (matched != 1) {
i++;
matched = boolToInt(options[i].equals(choice));
}
action[i].run();
我使用这样的方法将boolean
转换为integer
1=true, 0=false
public static int boolToInt(Boolean b) {
return 5 - b.toString().length();
}
相反,Runnable可以提供自己的界面。