I have an error on implementing a library module to my Android apps.
it says:
Constant expression required Resource IDs cannot be used in a switch statement in Android library modules less... (Ctrl+F1)
Validates using resource IDs in a switch statement in Android library module. Resource IDs are non final in the library projects since SDK tools r14, means that the library code cannot treat these IDs as constants.
and here is my code:
private void changeWeekStart(#IdRes int selection) {
switch (selection) {
case R.id.action_week_start_saturday:
CalendarUtils.sWeekStart = Calendar.SATURDAY;
break;
case R.id.action_week_start_sunday:
CalendarUtils.sWeekStart = Calendar.SUNDAY;
break;
case R.id.action_week_start_monday:
CalendarUtils.sWeekStart = Calendar.MONDAY;
break;
}
PreferenceManager.getDefaultSharedPreferences(this)
.edit()
.putInt(CalendarUtils.PREF_WEEK_START, CalendarUtils.sWeekStart)
.apply();
supportInvalidateOptionsMenu();
mCoordinator.reset();
}
Please help me to change from switch-case to if-else code.
thanks.
Everywhere you have a case, that will become the condition of an if statement; a break statement will correspond with a closing } on an if statement.
if (selection == R.id.action_week_start_saturday) {
CalendarUtils.sWeekStart = Calendar.SATURDAY;
} else if (selection == R.id.action_week_start_sunday) {
CalendarUtils.sWeekStart = Calendar.SUNDAY;
} else if (selection == R.id.action_week_start_monday) {
CalendarUtils.sWeekStart = Calendar.MONDAY;
}
Note that you do not supply a default case in your switch-case block so it is possible that CalendarUtils.sWeekStart is not modified if the selection parameter has a value different from the ones you've considered.
Related
This question already has answers here:
How to avoid a lot of if else conditions
(8 answers)
Closed 1 year ago.
I've got to do a check in my android app for orientation screen and after that to set the screen orientation to the next phase. I've run out of ideas how to do that avoiding this ugly else if block of code. Could you please give me a suggestion or something?
int currentOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; // Default orientation
.
.
.
switch (item.getItemId()) {
.
.
.
case R.id.change_orientation:
if (currentOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
currentOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
} else if (currentOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
currentOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
} else if (currentOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE) {
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
currentOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
}
Oops, I did not notice Android in your Question. I have no idea whether this works or not in current Android.
tl;dr
this.setRequestedOrientation(
switch ( currentOrientation )
{
case SCREEN_ORIENTATION_LANDSCAPE -> ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
case SCREEN_ORIENTATION_PORTRAIT -> ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
case SCREEN_ORIENTATION_REVERSE_LANDSCAPE -> ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
}
);
Switch expressions
You can use switch expressions in Java 14 and later. The switch can return a value. See JEP 361: Switch Expressions.
Note that switch expressions are “exhaustive”, meaning the compiler tells you if not all of the enum values are covered by your case statements. And therefore no need for a default: case as would otherwise be indicated for defensive programming.
I noticed you call the same method in each of your if cases. So we can move that to a single method call at the end.
package work.basil.enums;
public class App2
{
public static void main ( String[] args )
{
App2 app = new App2();
app.demo();
}
enum ActivityInfo
{
SCREEN_ORIENTATION_PORTRAIT,
SCREEN_ORIENTATION_LANDSCAPE,
SCREEN_ORIENTATION_REVERSE_LANDSCAPE
}
private void demo ()
{
ActivityInfo currentOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
ActivityInfo activityInfo =
switch ( currentOrientation )
{
case SCREEN_ORIENTATION_LANDSCAPE -> ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
case SCREEN_ORIENTATION_PORTRAIT -> ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
case SCREEN_ORIENTATION_REVERSE_LANDSCAPE -> ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
};
this.setRequestedOrientation( activityInfo );
}
private void setRequestedOrientation ( ActivityInfo activityInfo )
{
System.out.println( "Setting requested orientation to: " + activityInfo );
}
}
Further changes to switch being previewed, in Java 17, by the way. See JEP 406: Pattern Matching for switch (Preview).
Although I don’t understand Android very well, but you can use hashmap to achieve it.
//init a hashmap
Map<String, Map<Integer, Object>> configureMap = Maps.newHashMap();
//itemId means all values in item.getItemId()
configureMap.put("itemId", Maps.newHashMap());
//this can replace your if else in switch
configureMap.get("itemId").put(currentOrientation, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
......
Object orientation = configureMap.get(item.getItemId()).get(currentOrientation);
this.setRequestedOrientation(orientation);
currentOrientation = orientation;
You can also use ImmutableMap.of() to beautify the code.
You can use a map that contains the next orientation value according to the current one:
Map<Integer,Integer> next = new HashMap<>(4);
next.put(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
...
switch (...) {
case R.id.change_orientation:
int nextOrient = next.get(currentOrientation);
this.setRequestedOrientation(nextOrient); // Change this method so it also updates 'currentOrientation'
break;
Note that it would be more efficient to store those next orientation values into an array, search for the index of the current one and then do a (i+1)%4 to get the index of the next one. I'll leave that to you.
Use nested switch block; eg
switch(currentOrientation) {
case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
currentOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
break;
case y:
// code block
break;
default:
// code block
}
You can know more about switch here: https://www.w3schools.com/java/java_switch.asp
Current currentOrientation is of datatype int [https://developer.android.com/reference/android/content/pm/ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE]
others are also of data type int so comparison can be done, if it was of type Object, then we couldn't use Switch
you can use switch and also use ternatory operator (?) in java.
? operator is used for only 2 conditions. like {condition ? true : false}.
if you have more than one condition than you should go for switch.
I have 6 values in the enum and using 6 if-else is really a bad practice.
Can we implement this in any better way? Below is my scenario :
ExampleEnum value = getEnumValue();
if(ExampleEnum.A == value){
doA();
}else if(ExampleEnum.B == value){
doB();
}else if(ExampleEnum.C == value){
doC();
}else if(ExampleEnum.D == value){
doD();
}else if(ExampleEnum.E == value){
doE();
}else if(ExampleEnum.F == value){
doF();
}
I was thinking of switch, but is is not making much difference also i need to return a boolean value inside doA() depending on certain parameters.
Thanks in advance.
You have a few options:
A chain of else-ifs
Leave your code as-is. Hard to read and write.
Switch
switch (value) {
case A:
doA();
break;
case B:
doB();
break;
case C:
doC();
break;
case D:
doD();
break;
case E:
doE();
break;
case F:
doF();
break;
}
Note that this is the classic switch. If you have access to newer Java versions, it is probably possible to get rid of the breaks.
EnumMap
You can also create an EnumMap:
EnumMap<ExampleEnum, Runnable> enumMap = new EnumMap<>(Map.<ExampleEnum, Runnable>of(
ExampleEnum.A, Main::doA, // 'Main', or wherever your do* methods are.
ExampleEnum.B, Main::doB,
ExampleEnum.C, Main::doC, // I'm using method references. But you could
ExampleEnum.D, Main::doD, // also use lambda expressions: '() -> doD()'.
ExampleEnum.E, Main::doE,
ExampleEnum.F, Main::doF
));
ExampleEnum value = getEnumValue();
enumMap.get(value).run();
If you want to use a switch statement and you're on Java 12 or newer, consider using extended switch expressions that avoid the pitfalls of break statements:
switch (value) {
case A -> doA();
case B -> doB();
case C -> doC();
case D -> doD();
case E -> doE();
case F -> doF();
}
You can add the do method inside the enum.
public enum ExampleEnum {
A {
public void doIt() { ... }
},
B {
public void doIt() { ... }
},
...
abstract public void doIt();
}
ExampleEnum value = getEnumValue();
if (value != null) {
value.doIt();
}
Im selecting a "Left" from alert dialog and after putting it into convertStatusToCode function should retrun "4" but its not?
final String[] status = {"Left"};
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("Pick a Status");
builder.setItems(status, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
BookingStatus = convertStatusToCode(status[which]);
HERE IS MY convertStatusToCode FUNCTION but it is not retruning "4" which it should return.
private String convertStatusToCode(String status) {
switch (status) {
case "Processing":
i = "0";
break;
case "Room is Allotted":
i = "1";
break;
case "Sorry All Rooms Are Full":
i = "2";
break;
case "Living":
i = "3";
break;
case "Left":
i = "4";
break;
}
return i;
}
it should look something like this
String getStatusCode(String status) {
switch (status) {
case "Processing":
return "0";
case "Room is Allotted":
return "1";
case "Sorry All Rooms Are Full":
return "2";
case "Living":
return "3";
case "Left":
return "4";
default:
return "default_value";
}
}
Based upon what you've added in the comments, your Switch statement (albeit incomplete) shouldn't be the cause of your problem as the other posters are assuming.
You may have a problem with the completness of your switch cases, but that shouldn't stop the switch to work as intended.
You're saying that you DEBUG this and that i has the value of "" which I cannot understand unless you are not having a return value in scope.
The answer posted by Antonis Radz is how I would write that switch if I had to.
If you write your Convert function to return like so, then you don't need the extra i variable, which we don't know where you declared.
If you debug this line of code (like you said you did)
switch(value) and you're telling us that value == "Left" then the switch is receiving the correct value at runtime.
Now your "Case" is executed (when you set a breakpoint in case "Left". So the switch is, again, performing its function so far.
Then I assume you added another breakpoint in the following line(s):
i = "4";
break;
to see what is going on.
The first breakpoint would hit in the assignment i=... and so the variable i which I assume is declared somewhere in scope as String i (At the very least), is either null or contains an old value. Doesn't matter because the next breakpoint (in the break line) would be reached after i is assigned the value of the String "4". So if you add a watch to i and inspect it right there, it must have the value of "4".
Then you return this i so, again, it should still be "4".
If you did all this, you would have been able to tell much closer where the variable is not being assigned.
Do like this.
public String getstatuscode(String status){
String i="";
switch (status) {
case "Processing":
i = "0";
break;
case "Room is Allotted":
i = "1";
break;
case "Sorry All Rooms Are Full":
i = "2";
break;
case "Living":
i = "3";
break;
case "Left":
i = "4";
break;
default:
i = "-1";
}
return i;
}
Declare i as String or int as your requirement. Method is same.Don't forget to remove quotes if you want to assign i as int.
Another thought to use enum rather than switch-case here which gives more flexibility & reusability.
public enum BookingStatus
{
PROCESSING("Processing", 1),
ALLOTED_ROOM("Room is Allotted", 2),
ALL_FULL("Sorry All Rooms Are Full", 3),
LIVING("Living", 4),
LEFT("LEFT", 5);
private String status;
private int code;
BookingStatus(String status, int code)
{
this.status = status;
this.code = code;
}
public static BookingStatus getCodeFromStatus(String status)
{
for (BookingStatus e : values()) {
if (e.status.equals(status)) {
return e;
}
}
return null;
}
public static void main(String args[]) {
System.out.printf("Code for this status is %s", BookingStatus.getCodeFromStatus("Sorry All Rooms Are Full").code);
}
}
switch (status) {
case "Processing":
i = "0";
break;
case "Room is Allotted":
i = "1";
break;
case "Sorry All Rooms Are Full":
i = "2";
break;
case "Living":
i = "3";
break;
case "Left":
i = "4";
// return "4";
break;
}
return i;
}
use return "4"; you don't print anything in switch cases so switch can't return anything if you want to print in switch cases output then use the print method or return in any programming language.
public void select()
{
do
{
switch(info)
{
case'1':
case'a':
return System.out.println("Hello");
case'2':
case'b':
return selection = 'b';
default:
return System.out.println("Close");
}
}while(info != 'b');
}
So what would be the proper syntax and is this the even possible to do. New to Java
First, the loop is not needed, you can delete that. And you are using return statements wrongly. You cannot return
System.out.println();
Also, your method is declared to return void which means nothing. That means your return statement doesn't need anything else,just the word return.
return;
So my advice is that print the stuff first, and then return. And you should really read Java for Dummies, by Barry Burd.
1st of all you can't return anything from a void method, instead change it to char for example:
public char select () {
//read user input
char userInput = '1'; //change it as you wish or read from console
switch (userInput) {
case '1':
case 'a':
return 'a';
case '2':
case 'b':
return 'b';
//... and so on
default:
return '0'; //Or anything you want (but it MUST be a char (at least for my code, if you change it to String, you can return a word or well... a String)).
}
}
Then on main method (or the method which called select()) you add:
char selection;
selection = select();
System.out.println(selection);
If you want to add the switch into a loop (do-while as in your question), then you might want to do it this way on main method:
char selection;
do {
selection = select();
System.out.println(selection);
} while (selection != '0');
However I strongly recommend you to read Java Docs: Switch Statement and Returning a Value from a method which is actually what you're trying to achieve.
From second link you can confirm what I said before (on the 1st line of my answer and as some other users stated on comments)
Any method declared void doesn't return a value.
I am documenting some code using JD-GUI. Currently working on class that utilizes "XMLPullParser". I have read some documentation, but not really getting a clear picture.
The following is a snippet from a method, I want to know what this "eventType" is indication before and in the switch statement cases. What is the significance of it? The "parser" variable below is of type "XmlPullParser"
while (!poComplete)
{
int eventType = this.parser.next();
if (1 == eventType) {
break;
}
switch (eventType)
{
case 2:
String name = this.parser.getName();
if ("purchaseOrder".equals(name)) {
bufferingData = true;
}
if (bufferingData) {
buf.append("<").append(name).append(">");
}
break;
case 3:
if (bufferingData)
{
String name = this.parser.getName();
buf.append("</").append(name).append(">");
if ("purchaseOrder".equals(name))
{
poComplete = true;
bufferingData = false;
}
}
break;
case 4:
if (bufferingData) {
buf.append(quoteXmlData(this.parser.getText()));
}
break;
}
}
next() method returns eventType of integer.
it is one of the constants defined in XMLPullParser.
see javadoc