How can I convert the following code to switch statement?
String x = "user input";
if (x.contains("A")) {
//condition A;
} else if (x.contains("B")) {
//condition B;
} else if(x.contains("C")) {
//condition C;
} else {
//condition D;
}
There is a way, but not using contains. You need a regex.
final Matcher m = Pattern.compile("[ABCD]").matcher("aoeuaAaoe");
if (m.find())
switch (m.group().charAt(0)) {
case 'A': break;
case 'B': break;
}
You can't switch on conditions like x.contains(). Java 7 supports switch on Strings but not like you want it. Use if etc.
Condition matching is not allowed in java in switch statements.
What you can do here is create an enum of your string literals, and using that enum create a helper function which returns the matched enum literal. Using that value of enum returned, you can easily apply switch case.
For example:
public enum Tags{
A("a"),
B("b"),
C("c"),
D("d");
private String tag;
private Tags(String tag)
{
this.tag=tag;
}
public String getTag(){
return this.tag;
}
public static Tags ifContains(String line){
for(Tags enumValue:values()){
if(line.contains(enumValue)){
return enumValue;
}
}
return null;
}
}
And inside your java matching class,do something like:
Tags matchedValue=Tags.ifContains("A");
if(matchedValue!=null){
switch(matchedValue){
case A:
break;
etc...
}
#Test
public void test_try() {
String x = "userInputA"; // -- test for condition A
String[] keys = {"A", "B", "C", "D"};
String[] values = {"conditionA", "conditionB", "conditionC", "conditionD"};
String match = "default";
for (int i = 0; i < keys.length; i++) {
if (x.contains(keys[i])) {
match = values[i];
break;
}
}
switch (match) {
case "conditionA":
System.out.println("some code for A");
break;
case "conditionB":
System.out.println("some code for B");
break;
case "conditionC":
System.out.println("some code for C");
break;
case "conditionD":
System.out.println("some code for D");
break;
default:
System.out.println("some code for default");
}
}
Output:
some code for A
No you cannot use the switch with conditions
The JAVA 7 allows String to be used with switch case
Why can't I switch on a String?
But conditions cannot be used with switch
you can only compare the whole word in switch.
For your scenario it is better to use if
also HashMap:
String SomeString = "gtgtdddgtgtg";
Map<String, Integer> items = new HashMap<>();
items.put("aaa", 0);
items.put("bbb", 1);
items.put("ccc", 2);
items.put("ddd", 2);
for (Map.Entry<String, Integer> item : items.entrySet()) {
if (SomeString.contains(item.getKey())) {
switch (item.getValue()) {
case 0:
System.out.println("do aaa");
break;
case 1:
System.out.println("do bbb");
break;
case 2:
System.out.println("do ccc&ddd");
break;
}
break;
}
}
Related
I'm trying to migrate this C# code to Java.
Is there any possibility to migrate the unicodeCategory to a regex in Java, or is there a possibility to do the Unicode category by Java directly?
foreach (var currentChar in preNormalizedString)
{
var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(currentChar);
//https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=EN-US&k=k(System.Globalization.UnicodeCategory.LowercaseLetter);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.6);k(DevLang-csharp)&rd=true
switch (unicodeCategory)
{
//case UnicodeCategory.NonSpacingMark:
//case UnicodeCategory.SpacingCombiningMark:
//case UnicodeCategory.EnclosingMark:
case UnicodeCategory.DashPunctuation:
case UnicodeCategory.ConnectorPunctuation:
case UnicodeCategory.OpenPunctuation:
case UnicodeCategory.ClosePunctuation:
case UnicodeCategory.OtherPunctuation:
case UnicodeCategory.LineSeparator:
case UnicodeCategory.MathSymbol:
case UnicodeCategory.ModifierSymbol:
case UnicodeCategory.OtherSymbol:
case UnicodeCategory.SpaceSeparator:
case UnicodeCategory.ParagraphSeparator:
if (!isPreviousSpaceChar)
builder.Append(" ");
isPreviousSpaceChar = true;
break;
case UnicodeCategory.Control:
case UnicodeCategory.CurrencySymbol:
case UnicodeCategory.EnclosingMark:
case UnicodeCategory.NonSpacingMark:
case UnicodeCategory.SpacingCombiningMark:
case UnicodeCategory.InitialQuotePunctuation:
case UnicodeCategory.FinalQuotePunctuation:
case UnicodeCategory.Format:
case UnicodeCategory.ModifierLetter:
case UnicodeCategory.OtherNotAssigned:
case UnicodeCategory.PrivateUse:
case UnicodeCategory.Surrogate:
// Caratères ignorés.
break;
case UnicodeCategory.LowercaseLetter:
case UnicodeCategory.UppercaseLetter:
case UnicodeCategory.LetterNumber:
case UnicodeCategory.DecimalDigitNumber:
case UnicodeCategory.OtherLetter:
case UnicodeCategory.OtherNumber:
case UnicodeCategory.TitlecaseLetter:
default:
builder.Append(currentChar);
isPreviousSpaceChar = false;
break;
}
}
var normalizedString = builder.ToString() ?? string.Empty;
normalizedString = normalizedString.ToUpper();
normalizedString = normalizedString.Trim();
return normalizedString;
There is a getType(char) that will return an int that you can then compare with a list of constants that are enumerated in the Java Docs.
Note that both C# code and the getType(char) are "wrong" because they don't support non-BMP characters (characters that use two char). But splitting a string in its "Rune" was a little more complex in C# until .NET Core 3.0.
public static String convert(String preNormalizedString) {
StringBuilder builder = new StringBuilder();
boolean isPreviousSpaceChar = false;
for (int i = 0; i < preNormalizedString.length(); i++) {
char currentChar = preNormalizedString.charAt(i);
int unicodeCategory = Character.getType(currentChar);
switch (unicodeCategory) {
case Character.DASH_PUNCTUATION:
case Character.CONNECTOR_PUNCTUATION:
//... You'll have to complete the list
if (!isPreviousSpaceChar)
builder.append(" ");
isPreviousSpaceChar = true;
break;
case Character.CONTROL:
case Character.CURRENCY_SYMBOL:
//... You'll have to complete the list
// Caratères ignorés.
break;
case Character.LOWERCASE_LETTER:
case Character.UPPERCASE_LETTER:
//... You'll have to complete the list
default:
builder.append(currentChar);
break;
}
}
String normalizedString = builder.toString();
normalizedString = normalizedString.toUpperCase();
normalizedString = normalizedString.trim();
return normalizedString;
}
I am making a program which can make singular words plural, however I am unsure how I would go about checking the exceptions in the string array I created. I know there are more exceptions, but for now I just want to get what I have working. I made a method called "checkExceptions", but what would I put inside of it for the program to check that method first before moving on?
import java.util.Scanner;
public class FormingPlurals {
static final String SENTINEL = "done";
static final Scanner IN = new Scanner(System.in);
static String[] exceptions = {"fish", "fox", "deer", "moose", "sheep", "cattle"};
public static void run() {
while (true) {
System.out.println("Enter a word to make it plural. Enter 'done' to stop: ");
String noun = IN.nextLine();
if (noun.toLowerCase().equals(SENTINEL)) {
System.out.println("Goodbye...");
break;
}
System.out.println(makePlural(noun) + " ");
}
}
public static void checkExceptions() {
}
static String makePlural(String singularWord) {
String pluralWord = "";
int length = singularWord.length();
String checker = singularWord.substring(0, singularWord.length() - 1);
char lastLetter = singularWord.charAt(singularWord.length() - 1);
if (length == 1) {
pluralWord = singularWord + "'s";
} else
switch (lastLetter) {
case 's':
case 'x':
case 'z':
pluralWord = singularWord + "es";
break;
case 'h':
if ((singularWord.charAt(singularWord.length() - 2) == 'c') || (singularWord.charAt(singularWord.length() - 2) == 's')) {
pluralWord = singularWord + "es";
break;
}
case 'f':
if (EnglishConsonant(singularWord.charAt(singularWord.length() - 2))) {
pluralWord = checker + "ves";
break;
}
case 'y':
if (EnglishConsonant(singularWord.charAt(singularWord.length() - 2))) {
pluralWord = checker + "ies";
break;
}
default:
pluralWord = singularWord + "s";
break;
}
return pluralWord;
}
public static boolean EnglishConsonant(char ch) {
switch (Character.toLowerCase(ch)) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
return false;
default:
return true;
}
}
public static void main(String[] args) {
run();
}
}
It is also possible to do that with arrays, but it is easier to use a map in this case. You could create a map
Map<String,String> irregularPlurals = new HashMap<>();
irregularPlurals.put("sheep","sheep");
irregularPlurals.put("fox","foxes");
Then you could use simply Map interface's methods like get() or containsKey() to check if a given word is has an irregular plural form. A simple method to check it would then be:
String irregularPlural = irregularPlurals.get(singularWord);
if (irregularPlural != null){
return irregularPlural ;
}
BTW, it would be a good idea to rename the methods checkException(), as in Java exceptions and checked exceptions are language concepts, so a reader may think that that method is about handling Java exceptions.
For one, I'd place the exceptions array inside makePlural itself and handle it there.
Secondly, I'd go from the most specialized case to the least one, so
First look at word exceptions
Look at special plurals like 'es', 'ves' etc.
add 's' to the word and return it
Also, the moment I find a match in either the exceptions or special plurals, I'd calculate and immediately return the result, to prevent other rules from matching and adding more stuff to pluralWord
If I had to use a function for the exceptions, it would be
public static boolean isException(String word){
String[] exceptions={"fish", "deer"};
for(int i=0;i<exceptions.length();i++) {
if(exceptions[i].equals(word))
return true;
}
return false;
}
Given that I have the following finals:
private static final char CLIPPING_LOWER = 'c';
private static final char CLIPPING_UPPER = 'C';
private static final char RESET_LOWER = 'r';
private static final char RESET_UPPER = 'R';
private static final char LOAD_LOWER = 'l';
private static final char LOAD_UPPER = 'L';
private static final char QUIT_LOWER = 'q';
private static final char QUIT_UPPER = 'Q';
And consider the switch-case:
public void keyPressed(KeyEvent e)
{
char usersChoice = e.getKeyChar(); // get the user's choice
switch(usersChoice)
{
case LOAD_UPPER:
{
userPressedLoad();
break;
}
case LOAD_LOWER:
{
userPressedLoad();
break;
}
case RESET_LOWER:
{
userPressedReset();
break;
}
case RESET_UPPER:
{
userPressedReset();
break;
}
case CLIPPING_LOWER:
{
userPressedClipping();
break;
}
case CLIPPING_UPPER:
{
userPressedClipping();
break;
}
case QUIT_UPPER:
{
userPressedQuit();
break;
}
case QUIT_LOWER:
{
userPressedQuit();
break;
}
default:
break;
}
}
Is it possible to write a case for both c and C in one block (and also r and R ... etc) instead of writing a separate case for c and another case for C?
One solution to group the cases together
case LOAD_UPPER:
case LOAD_LOWER:
userPressedLoad();
break;
Another solution is to convert the input to uppercase and use only uppercase in switch statement
char usersChoice = Character.toUpperCase(e.getKeyChar());
case LOAD_UPPER:
userPressedLoad();
break;
You can user Character.toLowerCase with usersChoice, that way you don't have to handle 'R', 'C', etc.
http://docs.oracle.com/javase/6/docs/api/java/lang/Character.html#toLowerCase(char)
case CLIPPING_LOWER:
case CLIPPING_UPPER: {
userPressedClipping();
break;
}
Yes like this for instance:
case LOAD_UPPER: case LOAD_LOWER:
{
userPressedLoad();
break;
}
Not sure what I'm doing wrong here. But I want to change the card to the correct format.
For example given the card 1c change it to AC.
Here's some code I've been playing with:
public static void main(String[] args) {
String[] cards = {"1c", "13s"};
for (String card : cards) {
switch (card.toUpperCase()) {
case "1C":
card = card.toUpperCase().replace("1C", "AC");
break;
case "13S":
card = card.toUpperCase().replace("13S", "KS");
break;
default:
System.out.println(Arrays.toString(cards));
}
}
System.out.println(Arrays.toString(cards));
}
Any help would be great cheers.
Within the loop, card is just a local variable, and reassigning it doesn't modify the array cards. An immediate fix would be to index over the array so you can reference each element directly:
for (int i = 0; i < cards.length; i++) {
switch (cards[i].toUpperCase()) {
case "1C":
cards[i] = cards[i].toUpperCase().replace("1C", "AC");
break;
case "13S":
cards[i] = cards[i].toUpperCase().replace("13S", "KS");
break;
default:
System.out.println(Arrays.toString(cards));
}
}
Edit: to answer edhedges' comment, one would need to keep a counter variable outside the loop in order to keep using the enhanced-for syntax:
int i = 0;
for (String card : cards) {
switch (card.toUpperCase()) {
case "1C":
cards[i] = card.toUpperCase().replace("1C", "AC");
break;
case "13S":
cards[i] = card.toUpperCase().replace("13S", "KS");
break;
default:
System.out.println(Arrays.toString(cards));
}
i++;
}
Are you using Java 7? If you are not, you can't use Strings in cases.
See this problem and here(scroll down to Using Strings in switch Statements)
You can do this by the following code
public static void main(String[] args) {
String[] cards = {"1c", "13s"};
for (int i = 0 ; i < cards.length ; i++) {
switch (card[i].toUpperCase()) {
case "1C":
cards[i] = cards[i].toUpperCase().replace("1C", "AC");
break;
case "13S":
cards[i] = cards[i].toUpperCase().replace("13S", "KS");
break;
default:
System.out.println(Arrays.toString(cards));
}
}
System.out.println(Arrays.toString(cards));
}
In addition to #Paul Borella's answer I would say that this is only possible with Java 7. As Switch statement does not allow String as an expression. So you should get compilation error at line
switch(card.toUpperCase())
If you want to acheive the same functionality then you can go for Enum.
public enum Cards {
1C, 13S;
public String replacedString(){
case 1C : return "AC";
break;
case 13S : return "KS";
break;
default : return "";
}
}
public class A {
public void search(boolean[] searchList) {
// searchList array is used to identify what options to search for in a given order
// e.g. boolean [] searchList = new boolean [] {false, false, true, false};
boolean searchL = false;
boolean searchM = false;
boolean searchK = false;
boolean searchA = false;
if(searchList[0] == true) searchL = true;
if(searchList[1] == true) searchM = true;
if(searchList[2] == true) searchK = true;
if(searchList[3] == true) searchA = true;
if(searchL == true) // write a query to search for all Ls
if(searchM == true) // write a query to search for all Ms
...........
}
Is there a way I can simplify this code ?
#All : Sorry for posting a wrong question before. I was confused!
Thanks,
Sony
I am a big fan of enums:
public class A {
enum SearchType {
L, M, A, K;
}
public void search(SearchType type) {
switch (type) {
case L:
System.out.println("Searching for L");
break;
case M:
System.out.println("Searching for M");
break;
case A:
System.out.println("Searching for A");
break;
case K:
System.out.println("Searching for K");
break;
default:
System.out.println("what to do here?");
// throw exception?
}
note also: your scenario allowed more than one search boolean to be true at a time, I assumed that was not your goal, but if it is we can tweak this a bit.
You should convert your state into an enum. For example your search booleans seem to be exclusive so i would do something like this:
enum SearchOption {
searchA, searchK, searchL, searchM
}
// then you can do
SearchOption searchOption = searchA;
switch (searchOption) {
case searchA:
System.out.println("I am searching for A");
break;
case searchK:
System.out.println("I am searching for K");
break;
case searchL:
System.out.println("I am searching for L");
break;
case searchM:
System.out.println("I am searching for M");
break;
}
If your states aren't exclusive you should try build to build a super set of exclusive states initially.
Why don't employ OOP? Like:
public interface Seeker {
void seek();
}
public class LSeeker implements Seeker {
void seek() { System.out.println("Will search for L"); }
}
// ... More implementations of Seeker
public class SeekDriver {
void seek(Seeker seeker) { seeker.seek(); }
}
public class A {
public enum SearchOption {
SEARCH_L,
SEARCH_M,
SEARCH_A,
SEARCH_K;
}
/**
* Make them pass in an enum for your search.
* Pros: type safe, can only use the selections you give
* Cons: must add to the enum to add new types
* #param option
*/
public void enumSearch(SearchOption option) {
switch(option) {
case SEARCH_A:
System.out.println("I am searching for A");
break;
case SEARCH_K:
System.out.println("I am searching for K");
break;
case SEARCH_L:
System.out.println("I am searching for L");
break;
case SEARCH_M:
System.out.println("I am searching for M");
break;
}
}
/**
* Use a primitive for your input
* Pros: Gives you more options without updating the enum
* Cons: Users could enter input you don't really want them to use
* #param option
*/
public void charSearch(char option) {
switch(option) {
case 'a':
case 'A':
System.out.println("I am searching for A");
break;
case 'k':
case 'K':
System.out.println("I am searching for K");
break;
case 'l':
case 'L':
System.out.println("I am searching for L");
break;
case 'm':
case 'M':
System.out.println("I am searching for M");
break;
}
}
/**
* Use a primitive and don't even actually check it! Just run with it!
* #param option
*/
public void uncheckedSearch(char option) {
System.out.println("I am searching for " + option);
}
}
As per your comment, here's my updated example of that method - make sure the comment at the top is updated!
/**
* Perform the search based on the options provided
* The list should be in the order of L, M, A, K
* #note update this comment as more search options are added
* #param searchList the list of flags indicating what to search for
*/
public void search(boolean[] searchList) {
// as per docs, [0] denotes an L search:
if(searchList[0])
// write a query to search for all Ls
// as per docs, [1] denotes an M search:
if(searchList[1])
// write a query to search for all Ms
// as per docs, [2] denotes an A search:
if(searchList[2])
// write a query to search for all As
// as per docs, [3] denotes a K search:
if(searchList[3])
// write a query to search for all Ks
}
Latest idea:
// Use the SearchOption enum from above
Map<SearchOption, String> searches = new HashMap<SearchOption, String>();
public List<SearchResult> search(List<SearchOption> options) {
List<SearchResult> results = new LinkedList<SearchResult>();
for(SearchOption option : options) {
String query = searches.get(option);
SearchResult result = MySearchService.executeQuery(query);
results.add(result);
}
return results;
}
Like this: ?
public class A {
public void search() {
private static final int SEARCH_L = -1;
private static final int SEARCH_M = 0;
private static final int SEARCH_A = 1;
private static final int SEARCH_K = 2;
int status;
switch(status){
case SEARCH_L:
System.out.println("I am searching for L");
break;
case SEARCH_M:
System.out.println("I am searching for M");
break;
// Etc
default:
// Log error didn't hit a known status
break;
}
}