问题
Some context: I'm parsing an accounting ledger which has account1
and account2
as int
types. Each is a number in the range [0, 99999]. I have many combinations to consider.
Ideally I'd like to use something like
switch (account1, account2){
case (1,1):
/*account1 is 1, account2 is 1*/
case (2,1):
/*account1 is 2, account2 is 1*/
}
and so on. (I only need to consider about 20 possible combinations).
Is there a way I can achieve this in Java?
I've considered this question Storing number pairs in java
and could build an IntPair
class. Perhaps if I define bool equals
then I could switch
on an instance, in a similar manner in which you can switch on java.lang.String
.
回答1:
Alas this is not possible in Java. You can only switch on integral types, or a java.lang.String
from Java version 7. (You can't build this functionality into your own type by overriding equals
and hashCode
from java.lang.Object
).
But that could inspire you to make a hack:
switch (Integer.toString(account1) + "_" + Integer.toString(account2)){
case "1_1":
case "2_1":
}
I find this to be surprisingly readable.
回答2:
EDIT :
Maybe this ?
public enum Account{
ACC_512_401(512,401),
ACC_512_402(512,402);
private final int accA;
private final int accB;
Account(int accA, int accB){
this.accA=accA;
this.accB=accB;
}
private int getAccA(){
return accA;
}
private int getAccB(){
return accB;
}
public static Account getEnum(int accA, int accB){
for(Account acc : values()){
if(accA == acc.getAccA() && accB == acc.getAccB()){
return acc;
}
}
return null;
}
}
public class testswitch {
public static void main(String[] args) {
test(Account.getEnum(512, 401));
}
public static void test(Account acc){
switch (acc){
case ACC_512_401:
System.out.println("A");
break;
case ACC_512_402:
System.out.println("A");
break;
default:
break;
}
}
}
You do your switch over your enum.
EDIT : I added getEnum method to get value for int input. Now it's what you want I guess.
回答3:
One possible strategy is like this, a slight variation on @Morgan's answer:
public enum AccountRelationship {
BOSS_ACCOUNTS,
SECRET_SWISS_TAX_AVOIDING_ACCOUNTS,
OTHER;
}
public static final Map<AccountPair,AccountRelationship> relationships = new HashMap<>();
static {
relationships.put(new AccountPair(1,1),AccountRelationship.BOSS_ACCOUNTS);
relationships.put(new AccountPair(1,5),AccountRelationship.BOSS_ACCOUNTS);
relationships.put(new AccountPair(2,2),AccountRelationship.SECRET_SWISS_TAX_AVOIDING_ACCOUNTS);
}
public void doSomething(AccountPair pair) {
AccountRelationship rel = relationships.getOrDefault(pair, AccountRelationship.OTHER);
switch (rel) {
case BOSS_ACCOUNTS: receiveLotsOfBonus(); break;
case SECRET_SWISS_TAX_AVOIDING_ACCOUNTS: laughAllTheWayToTheBank(); break;
case OTHER: payLotsOfTaxes();
}
}
This separates the logic of determining what to do from calling the actions, making things a lot more readable and easier to extend. Not to mention that you can easily unit test everything separately.
As you can see, it's pretty verbose though.
It's got one other potential pitfall: the relationships
map. This is great if you have several account pairs that require the same action, but when you add a new value to AccountRelationship
, it's easy to forget to update this map too.
回答4:
Just for the fun of using primes: (it's safe in the mentioned range, but on high integers it will surely fail)
The case calculation will be done on compile-time.
public class Switch {
public static void main(String[] args) {
int i = 1;
int j = 2;
switch (i * 2 + j * 3) {
case 1 * 2 + 2 * 3:
System.out.println("match");
}
}
}
来源:https://stackoverflow.com/questions/41831061/switching-on-a-pair-of-ints