Using regex with sets in Java - java

I have a set in Java with different strings, such as '+Cat', '+Dog', etc. I also have a string as shown below.
animals = '+Cat|+Dog|+Goat'
Basically, if the set contains any of the animals listed in animals, I want to return false. How would I go about doing this? I am not sure if you can use regex with contains. Furthermore the fact that I have the + in my string complicates regex.

public boolean containCheck(Set<String> newset) {
String animals = "+Cat|+Dog|+Goat";
for (String op : animals.split("\\|")) {
if (newset.contains(op)) {
return false;
}
}
return true;
}

You can split the string in array and use a for loop to check it the set contains any element presents in the array.
public Boolean isContaining(String animals, Set<String> sets ) {
for (String s : animals.split("\\|")) {
for (String set : sets) {
if (s.equals(set)) {
return false;
}
}
}
return true;
}

Related

Is there a way to merge this 2?

I'm running out of idea of how will I merge this 2 conditions, it has the same return so I need to merge
if ((StringUtils.isBlank(ext))) {
return true;
}
for (String str : INVALID_EXTENSION_ARR) {
if (ext.matches(str)) {
return true;
} else if (ext.matches(str.toLowerCase())) {
return true;
}
}
You don't need a loop.
Populate INVALID_EXTENSION_ARR with values in lowercase:
private static final List<String> INVALID_EXTENSION_ARR = Arrays.asList("foo", "bar", "whatever"); // Note: All in lowercase!
Then it's just one line:
return StringUtils.isBlank(ext) || INVALID_EXTENSION_ARR.contains(ext.toLowerCase());
Note: I have assumed when you used matches() you meant to use equals().
——-
If the list of acceptable extensions is “large” (say, more than 10), you’ll get better performance if you use a Set instead of a List:
private static final Set<String> INVALID_EXTENSION_ARR = new HashSet<>(Arrays.asList("foo", "bar", "whatever"));
Or for recent java versions:
private static final Set<String> INVALID_EXTENSION_ARR = Set.of("foo", "bar", "whatever");
But you would be unlikely to notice much difference unless the size was more than say 100.
Assuming that the loop will always be entered into,
for (String str : INVALID_EXTENSION_ARR) {
if (StringUtils.isBlank(ext) || ext.matches(str)) {
return true;
} else if (ext.matches(str.toLowerCase())) {
return true;
}
}
but I think that way that had it was easier to read and does not need to re-evaluate StringUtils.isBlank(ext) every time.
It is helpful if you provide more context, but this is one of the ways you can compact it.
for (String str : INVALID_EXTENSION_ARR) {
if (StringUtils.isBlank(ext) || ext.toLowerCase().matches(str.toLowerCase())) {
return true;
}
}

How can I check if String contains the domain name listed in ArrayList having multiple domains in Java?

I'm trying to allow request from specific domains only which are listed in ArrayList, so I need to put a conditional check if URL contains the domains listed in ArrayList then allow otherwise throw an Exception.
Suppose my ArrayList = [abc.com, def.com, xyz.com]
I want to check if my URL contains any of these domains from ArrayList then return true else return false.
I tried below code, but it checks the domain name one by one.
However, it returns false if domain name is valid -
ArrayList = [abc.com, def.com, xyz.com]
public static boolean isListContainValidDomain(List<String> arraylist) {
String reqURL = "dev.def.com";
boolean isValid = true;
for (String str : arraylist) {
if(!reqURL.contains(str.toLowerCase())){
isValid = false;
}
}
return isValid;
}
Can anyone please help on this.
You should invert the condition. As it is now your function will only return true if your string contains all strings in the list.
public static boolean isListContainValidDomain(List<String> arraylist) {
String reqURL = "dev.def.com";
for (String str : arraylist) {
if (reqURL.contains(str.toLowerCase())) {
return true;
}
}
return false;
}
Why don't you construct a regex that incorporates all the domains. Basically your ArrayList = [abc.com, def.com, xyz.com] should be converted to a string that looks like (abc.com | def.com | xyz.com) then you can just do a single regex match.
You may be able to use Streams api:
public static boolean isListContainValidDomain(List<String> arraylist) {
final String reqURL = "dev.def.com";
boolean isValid = arraylist.stream().anyMatch(domain -> reqURL.contains(domain));
return isValid;
}
Since it would be possible for an url to have a domain name anywhere (abc.computer.xxx.com) I think you should use endsWith. Here is a solution using streams
boolean isOk = arrayList.stream().anyMatch( dom -> reqUrl.endsWith(dom.toLowerCase()));

All combinations of alphanumeric string, better way?

The input to the "alphaNumeric" function is a String which consists of alphanumeric characters that are all lower case, for example "hello123hello". I want to be able to check all upper/lower case letter combinations for this string through a check( ) function. (Eg. HeLlO123hELlo is one of the combinations to be checked). I have written code in Java to do this where I store the matching String into an ArrayList, but would like to know if there a better way to do this without the ArrayList. Also, am I correct in saying the worst case runtime of this is O(2^n)? Note: Check is a function that returns either true or false, depending on whether the correct String is passed to the function.
public static String alphaNumeric(String input) {
ArrayList<String> list = new ArrayList<String>();
alphaHelper(input, "", list);
return list.get(0);
}
private static void alphaHelper(String in, String current, ArrayList<String> list) {
if (in.length() == 0) {
if (check(current)) {
list.add(current);
}
} else if (Character.isLetter(in.charAt(0))) {
alphaHelper(in.substring(1),current+in.substring(0,1).toLowerCase(),list);
alphaHelper(in.substring(1),current+in.substring(0,1).toUpperCase(),list);
} else if (Character.isDigit(in.charAt(0))) {
alphaHelper(in.substring(1),current+in.substring(0,1),list);
} else {
return;
}
}
If you just want to remove the ArrayList without changing your basic algorithm, you can do this:
public static String alphaNumeric(String input) {
return alphaHelper(input, "");
}
private static String alphaHelper(String in, String current) {
String result = null;
if (check(current)) {
result = current;
} else if (Character.isLetter(in.charAt(0))) {
result = alphaHelper(in.substring(1),current+in.substring(0,1).toLowerCase());
if (result == null) result = alphaHelper(in.substring(1),current+in.substring(0,1).toUpperCase());
} else if (Character.isDigit(in.charAt(0))) {
result = alphaHelper(in.substring(1),current+in.substring(0,1));
}
return result;
}
Yes it is O(2^n), and I can't see offhand how you would improve on that if you can't get the original string directly.
If you don't need to check substrings (i.e. you only care about case variations of the entire string) you could improve the algorithm by not testing the substrings, but it would still be O(2^n).
You could temporarily set both the check and input to lowercase and compare them then.
public static boolean alphaNumeric(String input, String check) {
return input.toLowerCase().equals(check.toLowerCase());
}
-Sean

simple conditional in java (unexpected issue)

I have an unexpected issue when using a conditional operator in java.
The code is supposed to check if the ArrayList contains a specific string, then it returns true or false. It is not the first time I do this, but for some reason there's something wrong.
This is my code so far:
public boolean isDone() {
ArrayList<String> al = new ArrayList<String>(); //Defining ArrayList
al.add(d1.getText()); // Adding the text from JLabels.
al.add(d2.getText());
al.add(d3.getText());
al.add(d4.getText());
al.add(d5.getText());
if(al.contains(".")) {
return false;
} else {
return true;
}
The issue is that when running the debugger, it should return falseand instead of that, it returnstrue. For some reason the conditional is not "reading" the content of the ArrayList, or stuff like that.
As you see, the ArrayList contains the . that needs the conditional to return false, but instead of that, it returns true. What is wrong in my code?
Try this:
public boolean isDone() {
ArrayList<String> al = new ArrayList<String>();
al.add(d1.getText());
al.add(d2.getText());
al.add(d3.getText());
al.add(d4.getText());
al.add(d5.getText());
for (String str : al)
if (str != null && str.contains("."))
return false;
return true;
}
You have to check each string individually, the contains() method in ArrayList will return true only if the exact string "." is present in the list, not if one of the strings in the list contains a dot.
When you use a1.contains(...), you are checking if any sting in array is ".". This is different from your intention to check if any string in array "a1" contains '.' char as I understand.
If you need to check if any string in array contains "." text it can be like this:
for(String text : a1) {
if(text != null && text.indexOf(".") >= 0) {
return false;
}
}
return true;
Your List<String> does not contain the String that equals ".". You have a String that contains a . but that is not the same thing. You can do that with String.contains(CharSequence),
public boolean isDone() {
List<String> al = new ArrayList<String>(); // <-- I would use the Interface type
al.add(d1.getText());
al.add(d2.getText());
al.add(d3.getText());
al.add(d4.getText());
al.add(d5.getText());
// If any String in al contains a '.' return false, else true.
for (String str : al) {
if (str.contains(".")) {
return false;
}
}
return true;
}

Checking an array list against another array list

This is a method in a spell checker. As the header explains, it should return true if and only if all the words added to the arraylist are found in the parent array, words. Otherwise it should return a false value. I've been fighting with this for a few hours and this is my current situation...
/**
* This method returns true if (and only if) all words in the
* given wordList are found in the dictionary.
*/
public boolean allKnown(ArrayList<String> wordList)
{
boolean result = true;
for(int index = 0; index < wordList.size(); index++)
{
if(words.contains(!wordList.contains(index)))
{
result = false;
}
result = true;
}
return result;
}
All I really need is a way to turn out a yes or no, but I'm lost.
Please try and work with the code given as this is an exercise to teach that code.
Thanks!
Your problem is here:
if(words.contains(!wordList.contains(index)))
!wordList.contains(index) is a boolean expression, so it always evaluates to either true or false. So you're actually checking if the words list contains true or false, not the word like you want. Replace it with if(!words.contains(wordList.get(index)) to check if the current word is found in the dictionary.
I would suggest a following solution: iterate wordList word by word, and for each word check if it's found in the dictionary. If not so, return false immediately. If you reach the end of the loop, return true.
Here could be another solution:
public static boolean allKnown(List<String> parent, List<String> child) {
List<String> temp = new ArrayList<String>(child);
temp.removeAll(parent);
return temp.isEmpty();
}
For example:
List<String> parent = Arrays.asList("w1", "w2", "w3", "w4");
List<String> childOk = Arrays.asList("w1", "w4");
List<String> childKo = Arrays.asList("w1", "xx");
System.out.println(allKnown(parent, childOk));
System.out.println(allKnown(parent, childKo));
Prints:
true
false
Take out result = true; - you don't want to reset the value to true at every step in the loop.
Also change wordList.contains to wordList.get (because you want to get the word at a specific index, not check if it's contained in wordList) and move the ! out (because you can't 'not' a string).
And you can also optimize by checking result's value in the for-loop condition (or simply returning directly in the if-statement).
public boolean allKnown(ArrayList<String> wordList)
{
boolean result = true;
for(int index = 0; index < wordList.size() && result; index++)
{
if(!words.contains(wordList.get(index)))
{
result = false;
}
}
return result;
}
If words really is an array and not an ArrayList, it doesn't have a contains method, you'll have to either have a double for-loop, or convert it to a list:
List<String> parentWords = Arrays.asList(words);
...
if (parentWords.contains(...))
Don't reset result to true after your if. Because like this the whole function will always return true.
A few tips:
Don't use ArrayList as a method parameter, always use the more abstract List (none of your code depends on ArrayList, so you can change the implementation later, if you like).
Iterate over List objects using the simplified syntax shown below.
You only need one word to be not in the words list to return false, so do exactly that (as shown below).
public boolean allKnown(List<String> wordList) {
for (String word : wordList) {
if (!words.contains(word)) {
return false;
}
}
return true;
}
public boolean allKnown(ArrayList<String> wordList)
{
boolean result = true;
for(String word : wordList)
{
if(!words.contains(word))
{
result = false;
}
}
return result;
}
Here is a simpler version :
public boolean allKnown(List<String> wordList) {
List<String> wordListCopy = new ArrayList<String>(wordList);
return !wordListCopy.retainAll(words);
}
PS : retainAll() removes from you wordList all of its elements that are not contained in you dictionnary. This method return true if your wordList changed as a result of the call (after removing the non existing element), in other word, this method return false when all your wordList elements exists in you dictionnary.

Categories