1
    List list = new ArrayList();
    list.add("adminGroup");
    list.add("customerGroup");
    list.add("masterSalesGroup");
    System.out.println(list); //["adminGroup","customerGroup","masterSalesGroup"]
    list.contains("sales"); //false

expected output for list.contains("sales"); //true

I want to check whether list contains "sales". I need true if any list element contains "sales" word.

Amol
  • 7
  • 4
  • 2
    How should we do this without iterating over the list? It is not possible. – Turing85 Dec 23 '21 at 18:44
  • 1
    `contains` on a `List` *must* iterate the list. – xerx593 Dec 23 '21 at 18:45
  • ...until QuantumList... which will do it in constant time!;) – xerx593 Dec 23 '21 at 18:46
  • Does this answer your question? [How do I determine whether an array contains a particular value in Java?](https://stackoverflow.com/questions/1128723/how-do-i-determine-whether-an-array-contains-a-particular-value-in-java) – croakPedlar Dec 23 '21 at 18:47
  • @croakPedlar nope, not an exact dupe. – Turing85 Dec 23 '21 at 18:48
  • @Turing85 is this better? https://stackoverflow.com/questions/15824733/option-to-ignore-case-with-contains-method – croakPedlar Dec 23 '21 at 18:49
  • @croakPedlar wrt. behaviour: mostly yes (except for the ignore cases part). Problem is that the question - as OP asked - is not solvable. We have to iterate over the list one way or another to determine the desired result. – Turing85 Dec 23 '21 at 18:51
  • @Turing85 I was making an assumption that by "not wanting to iterate" they mean not wanting to do a loop? Fair that I shouldn't be making assumptions. OP 2 things. 1. Do these links help you? 2. With your example, do you need to ignore case? – croakPedlar Dec 23 '21 at 18:54

1 Answers1

0

expected output for list.contains("sales"); //true

This is cannot be done with standard JDK implementation of List/ArrayList.

Similarly, the input list needs to be iterated one way or another to check if any of its String entries contains the given substring, whether each entry is checked separately (in a loop or a stream) or whether all the entries are joined in a bigger string (using List::toString or String::join/ String::valueOf, etc.)

Assuming that the implicit iteration is not counted as "iteration", one of the possible solutions would be just to check if the list string representation contains the string:

list.toString().toLowerCase().contains("sales") // -> true

Another solution is to use String::matches (however, the search string needs to be surrounded with ".*" when building the regex pattern):

list.toString().matches("(?i).*sales.*"); // -> true
Nowhere Man
  • 19,170
  • 9
  • 17
  • 42
  • thanks a ton @Alex – Amol Dec 23 '21 at 19:12
  • 1
    If implicit iteration doesn’t count, a clean `list.stream().anyMatch(s -> s.contains("sales"))` is preferable over this `toString()` hack. – Holger Jan 03 '22 at 10:24
  • Happy New Year, @Holger! :) I mentioned the stream and did not consider as a solution because imo it uses iteration when each element of the list is checked separately while `toString` converts _somehow_ the entire list into a single entity. – Nowhere Man Jan 03 '22 at 10:41
  • 1
    I don’t think that it makes sense to separate these operations. `toString()` “somehow” converts the list into a string and `stream().anyMatch(…)` “somehow” checks whether at least one element fulfills the predicate. But your approach makes specific implicit assumptions about what `toString()` actually does. If a particular `List` implementation choses to do something else, your approach would break. In contrast, the Stream API abstracts from iteration as much as possible while still maintaining the necessary contract to do the intended thing. – Holger Jan 03 '22 at 10:59