How to use contains and equalsIgnoreCase in string - java

Is there a way to check if a string contains something while not being case sensitive?
For example: (this code is invalid it's just for you to get a basic understanding of my question)
String text = "I love ponies";
if(text.contains().equalsIgnoreCase("love") {
// do something
}
EDIT:
-------- Still not working
ooh, turns out it's not working. Here's what I'm using.
(it's a curse filter for a game)
public void onChat(PlayerChatEvent event) {
Player player = event.getPlayer();
if (event.getMessage().contains("douche".toLowerCase()) || /* More words ... */) {
event.setCancelled(true);
player.sendMessage(ChatColor.GOLD + "[Midnight Blue] " + ChatColor.RED + "Please Don't Swear.");
}
}
It works with lowercase but not uppercase.

return text.toLowerCase().contains(s2.toLowerCase());
Or another way would be
Pattern.compile(Pattern.quote(s2), Pattern.CASE_INSENSITIVE).matcher(text).find();

It would be easier if you use StringUtils#containsIgnoreCase from Apache Commons library
If you can't add a third party library, you can still use the code because is free to use. Check the online source code.
Test:
public class QuestionABCD {
public static boolean containsIgnoreCase(String str, String searchStr) {
if (str == null || searchStr == null) {
return false;
}
int len = searchStr.length();
int max = str.length() - len;
for (int i = 0; i <= max; i++) {
if (str.regionMatches(true, i, searchStr, 0, len)) {
return true;
}
}
return false;
}
public static void main(String[] args) {
System.out.println(containsIgnoreCase("abc", "A"));
System.out.println(containsIgnoreCase("abc", "a"));
System.out.println(containsIgnoreCase("abc", "B"));
System.out.println(containsIgnoreCase("abc", "b"));
System.out.println(containsIgnoreCase("abc", "z"));
System.out.println(containsIgnoreCase("abc", "Z"));
}
}
Output:
true
true
true
true
false
false

If case sensitivity is your only issue convert everything into lowercase
String text = "I love ponies";
String test = "LOVE";
if(text.toLowerCase().contains(test.toLowerCase()))
{
//your code
}
update:
for your code use :
event.getMessage().toLowerCase().contains("douche".toLowerCase())
in all the conditions

You can check twice like this
text.contains(s);
text.contains(s.toLowerCase());

Related

Method to check "dutch" postal code in java

I'm trying to create a method in java to validate a dutch postal code.
the dutch postal code consist 6 characters which contain 4 numbers (first 4 chars) and 2 letters (last 2 chars) so for example 1010AB.
I made a boolean to return false if the postcode is not within standard and true if it is.
I'm getting stuck with checking the last 2 letters.
I've created a loop for the first 4 numbers, but I don't know how to go further from here to check the letters aswell.
My java method:
public static boolean checkPostcode(String postCode) {
boolean value = false;
if (postCode.length() == lengthPost) {
for (int i = 0; i < postCode.length(); i++) {
if (i <= 4) {
if (Character.isDigit(postCode.charAt(i)) {
value = true;
else{
if (Character.isLetter(postCode.charAt(i))) {
value = true;
}
}
}
}
}
}
return value;
}
You van ignore the last else, because that is the point where I get stuck....
If someone can help me that would be great!!
Thanks in advance
Solution using regex:
public class Main {
public static void main(String[] args) {
// Tests
System.out.println(checkPostcode("1234AB"));
System.out.println(checkPostcode("5678MN"));
System.out.println(checkPostcode("0123AB"));
System.out.println(checkPostcode("1023AB"));
System.out.println(checkPostcode("1230AB"));
System.out.println(checkPostcode("AB1234"));
System.out.println(checkPostcode("123456"));
System.out.println(checkPostcode("ABCDEF"));
System.out.println(checkPostcode("12345A"));
System.out.println(checkPostcode("A12345"));
System.out.println(checkPostcode("A12345B"));
System.out.println(checkPostcode("1ABCDE6"));
System.out.println(checkPostcode("1ABCD6"));
}
public static boolean checkPostcode(String postCode) {
return postCode.matches("[1-9]{1}[0-9]{3}[a-zA-Z]{2}");
}
}
Output:
true
true
false
true
true
false
false
false
false
false
false
false
false
Non-regex solution:
public static boolean checkPostcode(String postCode) {
if (postCode.length() != lengthPost || postCode.charAt(0) == '0') {
return false;
}
if (postCode.length() == lengthPost) {
for (int i = 0; i < postCode.length(); i++) {
if (i < 4 && Character.isLetter(postCode.charAt(i))) {
return false;
}
if (i > 3 && Character.isDigit(postCode.charAt(i))) {
return false;
}
}
}
return true;
}
If I understand correctly, the first 4 symbols are digits, so the if condition should be
(i < 4)
because otherwise you check the first 5 symbols for a digit
While you could solve this problem with regular expressions, it is also possible to solve it along the lines you have chosen. I would write two helper methods, one to check that all characters within a given subsequence of a String are digits and another to check for letters. Like,
private static boolean allDigits(String s, int start, int end) {
for (int i = start; i < end; i++) {
if (!Character.isDigit(s.charAt(i))) {
return false;
}
}
return true;
}
private static boolean allLetters(String s, int start, int end) {
for (int i = start; i < end; i++) {
if (!Character.isLetter(s.charAt(i))) {
return false;
}
}
return true;
}
Then the checkPostcode can delegate to those two methods. Like,
public static boolean checkPostcode(String postCode) {
if (postCode != null && postCode.length() == 6) {
return allDigits(postCode, 0, 4) && allLetters(postCode, 4, 6);
}
return false;
}
And if you choose to use a regular expression compile it with a Pattern for better performance. Like,
private static Pattern POSTCODEPATTERN = Pattern.compile("\\d{4}[A-Za-z]{2}");
public static boolean checkPostcode(String postCode) {
return postCode != null && POSTCODEPATTERN.matcher(postCode).matches();
}

Java: Comparing String

I am trying to compare two Strings based on which the boolean dontuse will be set. For practice I have set string as static but they may vary (Please dont ask how I get these Strings it a whole big beast in itself).
What I am trying to do is, check if String 'allofmycode' has any element more then 'codeChoosen' then 'dontuse' is false. But if both of the string are equal then its is false or if the string has same element written several times then also false.
So, for
(1) it will be false as it contains AB & CD which are extra.
(2) will be true as it has the same element but is duplicate.
I hope it make sense, any suggestions or help? Thanks
public static void main(String[] args) {
boolean dontuse = false;
String codeChoosen = "EX,ZX";
String allofmycode = "EX,AB,CD,EX"; //(1) dontuse=false
//String allofmycode = "EX,EX,ZX"; //(2) dontuse =true
List<String> mycodeChoosen = Arrays.asList(codeChoosen.split("\\s*,\\s*"));
System.out.println("Selected : \t " + mycodeChoosen);
List<String> allofmyresult = Arrays.asList(allofmycode.split("\\s*,\\s*"));
System.out.println("All : \t" + allofmyresult);
if (mycodeChoosen.equals(allofmyresult)) {
dontuse = true;
} else {
for (int i = 0; i < mycodeChoosen.size(); i++) {
if (allofmyresult.contains(mycodeChoosen.get(i))) {
System.out.println(mycodeChoosen.get(i));
}
}
}
System.out.println("\n[DONT USE IS] : \t " + dontuse);
}
For example in basic english, If you have Apple, Orange and Banana; and I say people with Apple and Orange are not coming to my party. But you also have Banana so you are allowed to come to the party. But if you had two Apples or Apple and Banana then you are not allowed. I hope it make sense.
dontuse = !allofmyresult.stream().anyMatch(str -> !mycodeChoosen.contains(str));
As the problem seems to require only a view as sets, do:
static Set<String> codes(String list) {
Set<String> set = new HashSet<>();
Collections.addAll(set, list.split("\\s*,\\s*"));
return set;
}
String codeChoosen = "EX,ZX";
String allofmycode = "EX,AB,CD,EX"; //(1) dontuse=false
Set<String> choosen = codes(codeChoosen);
Set<String> all = codes(allofmycode);
boolean dontuse = choosen.equals(all);
// all.containsAll(choosen)
The original code probably was meant to do:
if (mycodeChoosen.equals(allofmyresult)) {
dontuse = true;
} else {
dontuse = true;
for (int i = 0; i < mycodeChoosen.size(); i++) {
if (allofmyresult.contains(mycodeChoosen.get(i))) {
dontuse = false;
break;
}
}
}

Recursion to check if a String equals another string

my current code returns the output:
true
Expected: true
false
Expected: true
false
Expected: true
false
Expected: false
false
Expected: false
So there's an issue with my logic that i'm not seeing
public static void main(String[] args)
{
System.out.println(find("",""));
System.out.println("Expected: true\n");
System.out.println(find("Mitten","Mit"));
System.out.println("Expected: true\n");
System.out.println(find("I love my CS courses!"," CS"));
System.out.println("Expected: true\n");
System.out.println(find("","Cookies."));
System.out.println("Expected: false\n");
System.out.println(find("Java","Python"));
System.out.println("Expected: false\n");
}
public static boolean find(String text, String str)
{
boolean found = false;
if(text.length() == 0 && str.length() == 0)
{
found = true;
return found;
}
if(text.length() == 0 || str.length() == 0)
{
return found;
}
if(str.length() > text.length())
{
return found;
}
if(str.equals(text.substring(0,str.length()-1)))
{
found = true;
}
else
{
text = text.substring(1);
find(text, str);
}
return found;
}
please help
I see an issue with this statement
if(str.equals(text.substring(0,str.length()-1)))
Since the second index of substring is exclusive, it should be
if(str.equals(text.substring(0,str.length())))
in order to compare str to the first str.length characters of text.
Of course you can use text.contains(str) or text.startsWith(str) and eliminate some of your code, but perhaps that's not part of the exercise requirements.
Beside that issue, when you make a recursive call, you should usually do something with the value returned by that call :
found = find(text, str);
otherwise, why make the recursive call in the first place? (unless it has side effects of mutating the objects passed as parameters to the recursive call, which it does not in your case)

What approach/method to use instead of multiple if statements

I have a java web app that asks the user to select between 4 options. They can choose 1, all, or any combination of the 5 options. Their choices are read into a Hashmap with true/false values. If the option is selected it's true, unselected is false. Depending on what the user chooses, a different file is selected from the resources folder to be processed. My problem is that the code is just a complete mess of logic and I'm sure that there's an easier way to implement it. The following is dummy code for my problem.
public class offerSelector {
public void selectOffer(Map params) {
/* Map params = Map<String, String> params = new HashMap <>();
It contains values ("internet","true),("phone","true"),("tv","true"),("cell","true")
*/
boolean option_1 = params.get("internet");
boolean option_2 = params.get("phone");
boolean option_3 = params.get("tv");
boolean option_4 = params.get("cell");
File offer = null;
if (option_1 == true && option_2 == false && option_3 == false && option_4 == false) {
offer = new File("internet_order");
}
else if(option_1 == false && option_2 == true && option_3 == false && option_4 == false) {
offer = new File("phone_order");
}
//continues like so with all possible combinations
else if(option_1 == true && option_2 == true && option_3 == true && option_4 == true) {
offer = new File("all_elements_order");
}
processOrder(offer);
}
}
I am a big fan Of pushing this parsing into a custom Object like
public class SomeObject
{
public SomeObject(Values)
{
this.options1 = //Something
this.options2 = //Something
this.options3 = //Something
this.options4 = //Something
}
public boolean isPhone() {return option1 && option2 && option3 && !option4;}
}
Then when you use the option you can do:
var x = new SomeObject(Values);
if (x.isPhone) {
// DO IS PHONE Branch
}
if (x.isFax) {
// DO IS Fax Branch
}
This is better because the parsing logic is excluded to a single class with a single responsibility. and then its clear in your if block what you are looking at.
The other options is to return an Enum from you SomeObject class and use a true case/switch statement.
There are a lot of solutions. For example the following.
Define interface Action:
interface Action {
boolean apply(Map<String, String> params);
void perform(Map<String, String> params);
}
Define enum Actions:
enum Actions implement Action {
ONE {
boolean apply(Map<String, String> params) {/*implement it*/}
void perform(Map<String, String> params) {/*implement it*/}
},
TWO {
boolean apply(Map<String, String> params) {/*implement it*/}
void perform(Map<String, String> params) {/*implement it*/}
},
;
//etc.
}
Implement your logic inside the call back methods. Obviously give the enum constants normal names.
Now your code can look like:
public void selectOffer(Map params) {
for (Actions a : Actions.values()) {
if (a.apply(params)) {
return a.perform(params);
}
}
}
You could try and use a custom object, let's say Options:
//note that a lot of common stuff like constructors or modifiers are stripped for simplicity
class Options {
boolean internet;
boolean phone;
...
public void equals( Object other) {
return other != null &&
other.getClass().equals( getClass()) &&
other.internet == this.internet &&
other.phone == this.phone &&
...
}
public int hashCode() {
//left for your excerise, should match equals
}
}
Map<Options, File> files = ...; //create and fill
Then parse the boolean parameters and create an Options instance which you use to look up the file in the map, e.g.:
Options paramOptions = new Options(/*booleans parsed from params*/);
offer = files.get( paramOptions );
Use a binary notation. each bit represents one option:
option4 is true, option3 is true, option2 is false and option1 is false will be 1100
1100 bin = 12 dec.
Each combination stands for a decimal number, which you can use in a switch statement.
I hope you understand what I mean.
Encapsulate it all away. Hide the details of sifting through the permutations of options in the guts of another class. Something like this...
//controller code
Boolean internet= params.get("internet");
Boolean phone = params.get("phone");
Boolean tv= params.get("tv");
Boolean cell = params.get("cell");
File offer = FileHelper(internet, phone, tv, cell);
//end controller code ...
public class FileHelper {
private final String PHONE = "phone_order";
private final String INTERNET= "internet_order";
private final String CELL= "cell_order";
private final String TV = "tv_order";
private final String ALL = "all_elements_order";
private boolean[] options;
public FileHelper(Boolean phone, Boolean internet, Boolean cell, Boolean tv) {
options = new boolean[4];
options[0] = phone == null ? false : phone;
options[1] = internet == null ? false : internet ;
options[2] = cell== null ? false : cell;
options[3] = tv == null ? false : tv ;
}
public File getOffer() {
File f;
if ( includeAll()) f = new File(ALL);
if ( phoneOffer()) f = new File(PHONE);
if ( internetOffer()) f = new File(INTERNET);
// .... and so on
return f;
}
private boolean includeAll() {
for(boolean b : options) {
if (!b) return false;
}
return true;
}
private boolean internetOffer() {
return getSingleOption() == 1;
}
private boolean phoneOffer() {
return getSingleOption() == 0;
}
private int getSingleOption() {
int i = -1;
for(int j; j =0; j++) {
if(options[j]) {
if ( i >= 0) {
return -1; //user has selected > 1 option
} else {
i = j;
}
}
}
return i;
}
}
I'm guessing the boolean[] won't be popular, but I think having such a structure gives you an easy way to determine how many options the user has flagged as true, which from your question seems like something you'd want to know.
Sorry not enought reputation to comment,
first of all you can use switches: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html, it is much easier for codes like this one, and maybe for organization you can use another function that is launched from this one (Just remember to put that strings univeral)

Sort algorithm problems on java comparable

I want to do a specific sort. I am using java's comparable interface which means the return of my compare method must return -1 +1 or 0 depending on the equality of the two compared, then I am sorting using Collections. My trouble comes from how I wish to compare.
I have a key that is made up of either of the following
[keyName]
[siteName].[keyName]
[siteName].[pageName].[keyName]
so as an example "mysite.alampshade.color"
the tricky part is the sites must be sorted first, followed by keyname, followed by pageName. but firstly by the keynames, then site name, in the order of the number of sections to the property. Sorry. its a little complicated, an example may help. here is the order they must be:
alpha
beta
charlie
sitea.alpha
sitea.charlie
sitea.pagea.beta
sitea.pageb.beta
sitea.pagea.charlie
siteb.alpha
siteb.delta
siteb.pagef.alpha
siteb.pageb.echo
siteb.pageb.golf
siteb.pagea.hotel
siteb.pageb.hotel
siteb.pagec.hotel
I have tried many different ways and have thrown away code a few times but still cant get it perfect. some pseudocode would be of great help if not some java.
EDIT:
to add another possibly simplier to understand example
the following is sorted how I need it
a
b
c
z
a.b
a.c
a.d
a.z
a.b.a
a.c.a
a.b.b
a.b.c
a.c.c
a.a.d
b.a
b.b
b.z
b.a.a
b.b.a
b.a.b
c.c.f
Another option, making it recursive you avoid the problem if there is ever more entries.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class SortTest {
public static void main(String[] args) {
String[] test = new String[]{
"a",
"b",
"b.a",
"b.a.a",
"a.a.a",
"a.b.a",
"a.a",
"a.b",
"b.a.b",
"b.b.a"
};
Arrays.sort(test, new Comparator<String>() {
int compareComplexList(List<String> a, List<String> b, List<int[]> positions, int order ) {
int minimum = a.size() < b.size() ? a.size() - 1 : b.size() - 1;
if (a.get(positions.get(minimum)[order]).compareTo(b.get(positions.get(minimum)[order])) != 0)
return a.get(positions.get(minimum)[order]).compareTo(b.get(positions.get(minimum)[order]));
else if (order < minimum - 1) return compareComplexList(a,b, positions, ++order);
else return Double.compare(a.size(),b.size());
}
public int compare(String a, String b) {
List<String> partsA = Arrays.asList(a.split("\\."));
List<String> partsB = Arrays.asList(b.split("\\."));
List<int[]> orders = new ArrayList<int[]>();
orders.add(new int[] {0});
orders.add(new int[] {0,1});
orders.add(new int[] {0,2,1});
return compareComplexList(partsA, partsB, orders,0);
}
});
System.out.println("Sorted: "+Arrays.toString(test));
}
}
Should be good now.
public int compare(String a, String b) {
String[] partsA = a.split("\\.");
String[] partsB = b.split("\\.");
// If first term is different, we exit.
if (partsA[0].compareTo(partsB[0]) != 0) return partsA[0].compareTo(partsB[0]);
// Else, first term is identical.
else {
// Same number of parts
if (partsA.length == partsB.length) {
// 2 parts, we compare the 2nd part.
if (partsA.length == 2) {
return partsA[1].compareTo(partsB[1]);
// 3 parts, we compare the 3rd part first, then the 2nd part
} else {
if (partsA[2].compareTo(partsB[2]) != 0) return partsA[2].compareTo(partsB[2]);
return partsA[1].compareTo(partsB[1]);
}
// Different number of parts
} else {
// If A has only 1 part, it's first
if (partsA.length == 1) return -1;
// If B has only 1 part, it's first
if (partsB.length == 1) return 1;
// Case 2 vs 3 parts, we compare the 3rd part with the 2nd part of the other. If it's equal, the shorter is first.
if (partsA.length == 3) {
if (partsA[2].compareTo(partsB[1]) != 0) return partsA[2].compareTo(partsB[1]);
else return 1;
} else {
if (partsA[1].compareTo(partsB[2]) != 0) return partsA[1].compareTo(partsB[2]);
else return -1;
}
}
}
}
My other answer started getting too gnarly. Here's a better, more natural solution:
public class StrangeComparator {
private static class Entry implements Comparable<Entry> {
// What to split with.
static final String dot = Pattern.quote(".");
// The parts.
final String key;
final String page;
final String site;
public Entry(String s) {
String [] parts = s.split(dot);
switch (parts.length) {
case 1:
key = parts[0];
page = "";
site = "";
break;
case 2:
key = parts[1];
page = "";
site = parts[0];
break;
case 3:
key = parts[2];
page = parts[1];
site = parts[0];
break;
default:
throw new IllegalArgumentException("There must be at least one part to an entry.");
}
}
#Override
public int compareTo(Entry t) {
int diff = site.compareTo(t.site);
if ( diff == 0 ) {
diff = page.compareTo(t.page);
}
if ( diff == 0 ) {
diff = key.compareTo(t.key);
}
return diff;
}
#Override
public String toString () {
return (site.length() > 0 ? site + "." : "")
+ (page.length() > 0 ? page + "." : "")
+ key;
}
}
public void test() {
String[] test = new String[]{
"alpha",
"beta",
"charlie",
"zeta", // Added to demonstrate correctness.
"sitea.alpha",
"sitea.charlie",
"sitea.pagea.beta",
"sitea.pageb.beta",
"sitea.pagea.charlie",
"siteb.alpha",
"siteb.delta",
"siteb.pagef.alpha",
"siteb.pageb.echo",
"siteb.pageb.golf",
"siteb.pagea.hotel",
"siteb.pageb.hotel",
"siteb.pagec.hotel"
};
Arrays.sort(test);
System.out.println("Normal sort: " + Separator.separate("\n", "\n", test));
Entry[] entries = new Entry[test.length];
for ( int i = 0; i < test.length; i++ ) {
entries[i] = new Entry(test[i]);
}
Arrays.sort(entries);
System.out.println("Special sort: " + Separator.separate("\n", "\n", entries));
}
public static void main(String args[]) {
new StrangeComparator().test();
}
}
Output order is:
alpha
beta
charlie
zeta
sitea.alpha
sitea.charlie
sitea.pagea.beta
sitea.pagea.charlie
sitea.pageb.beta
siteb.alpha
siteb.delta
siteb.pagea.hotel
siteb.pageb.echo
siteb.pageb.golf
siteb.pageb.hotel
siteb.pagec.hotel
siteb.pagef.alpha
Which kinda does what you say but doesn't match your example.
Here's an alternative - if a component is found to contain less that 3 parts then parts are added at the start to take up the slack. It then uses a sort order array to define which columns should be compared next:
public void test() {
String[] test = new String[]{
"alpha",
"beta",
"charlie",
"zeta", // Added to demonstrate correctness.
"sitea.alpha",
"sitea.charlie",
"sitea.pagea.beta",
"sitea.pageb.beta",
"sitea.pagea.charlie",
"siteb.alpha",
"siteb.delta",
"siteb.pagef.alpha",
"siteb.pageb.echo",
"siteb.pageb.golf",
"siteb.pagea.hotel",
"siteb.pageb.hotel",
"siteb.pagec.hotel"
};
Arrays.sort(test);
System.out.println("Normal sort: "+Arrays.toString(test));
Arrays.sort(test, new Comparator<String>() {
// How many columns to pad to.
final int padTo = 3;
// What to pad with.
final String padWith = "";
// What order to compare the resultant columns in.
final int[] order = {0, 2, 1};
#Override
public int compare(String s1, String s2) {
String[] s1parts = padArray(s1.split(Pattern.quote(".")), padTo, padWith);
String[] s2parts = padArray(s2.split(Pattern.quote(".")), padTo, padWith);
int diff = 0;
for ( int i = 0; diff == 0 && i < order.length; i++ ) {
diff = s1parts[order[i]].compareTo(s2parts[order[i]]);
}
return diff;
}
String [] padArray(String[] array, int padTo, String padWith) {
String [] padded = new String[padTo];
for ( int i = 0; i < padded.length; i++ ) {
padded[padded.length - i - 1] = i < array.length ? array[i]: padWith;
}
return padded;
}
});
System.out.println("Special sort: "+Arrays.toString(test));
}
prints (more or less):
Normal sort: [alpha,
beta,
charlie,
sitea.alpha,
sitea.charlie,
sitea.pagea.beta,
sitea.pagea.charlie,
sitea.pageb.beta,
siteb.alpha,
siteb.delta,
siteb.pagea.hotel,
siteb.pageb.echo,
siteb.pageb.golf,
siteb.pageb.hotel,
siteb.pagec.hotel,
siteb.pagef.alpha,
zeta]
Special sort: [alpha,
beta,
charlie,
sitea.alpha,
sitea.charlie,
siteb.alpha,
siteb.delta,
zeta,
siteb.pagef.alpha,
sitea.pagea.beta,
sitea.pageb.beta,
sitea.pagea.charlie,
siteb.pageb.echo,
siteb.pageb.golf,
siteb.pagea.hotel,
siteb.pageb.hotel,
siteb.pagec.hotel]
There does seem to be some ambiguity in your requirements but this code is structured so you can, with trivial tweaks, achieve most interpretations of your comparison quite simply.

Categories