Reputation: 794
See this code: (This is working code but I don't like to use 2 lines so looking for how can I make it better)
ItemDetails[] items = response.getDetailsList();
items = Arrays.stream(items).filter(x -> !x.getName().equalsIgnoreCase("acl1")).toArray(ItemDetails[]::new);
items = Arrays.stream(items).filter(x -> !x.getName().equalsIgnoreCase("acl2")).toArray(ItemDetails[]::new);
I could not figure how to use an OR (|)
condition within filter
to remove two specific elements from List
since it would give me compile time error (in IDE) and I end up using two filters
like above.
What could I be missing?
This is how I tried to use OR
items = Arrays.stream(items).filter(x -> !x.getName().equalsIgnoreCase("acl1") ||
x -> !x.getName().equalsIgnoreCase("acl2")).toArray(ItemDetails[]::new);
=> IntelliJ would complain about this one (above)
items = Arrays.stream(items).filter(x -> !x.getName().equalsIgnoreCase("acl1"") ||
x.getName().equalsIgnoreCase("acl2")).toArray(ItemDetails[]::new);
Does not work at runtime (it does not filter)
Entire code with commented code (which I tried) for reference
public static void mapTest () {
AclDetailItem[] items = new AclDetailItem[3];
AclDetailItem item1 = new AclDetailItem();
item1.setAclName("acl1");
AclDetailItem item2 = new AclDetailItem();
item2.setAclName("acl2");
AclDetailItem item3 = new AclDetailItem();
item3.setAclName("acl3");
items[0] = item1;
items[1] = item2;
items[2] = item3;
System.out.println ("Before " + items.length);
items = Arrays.stream(items).filter(x -> !x.getAclName().equalsIgnoreCase("acl1")).toArray(ItemDetails[]::new);
items = Arrays.stream(items).filter(x -> !x.getAclName().equalsIgnoreCase("acl2")).toArray(ItemDetails[]::new);
System.out.println ("After " + items.length);
}
Upvotes: 10
Views: 34928
Reputation: 9
Question is "filter out with certain condition from Male or Female with one line"
with consumer implementation for printing
Answer
--------
public class Emp{
private String name;
private int age;
private String gender; with setter, getter Allargument constructor}
public class MailFemaleFilter {
public static void main(String[] args) {
List<Emp> empli=new ArrayList<Emp>();
empli.add(new Emp("A",33,"m"));
empli.add(new Emp("B",26,"m"));
empli.add(new Emp("C",18,"m"));
empli.add(new Emp("D",90,"m"));
empli.add(new Emp("E",45,"m"));
//female
empli.add(new Emp("A1",7,"f"));
empli.add(new Emp("B1",29,"f"));
empli.add(new Emp("C1",70,"f"));
empli.add(new Emp("D1",23,"f"));
empli.add(new Emp("E1",39,"f"));
//creation of predicate
Predicate<Emp> agetest = e-> e.getAge() > 30;
Predicate<Emp> genderMtest = m-> m.getGender().equals("m");
Predicate<Emp> genderFtest = mf-> mf.getGender().equals("f");
List<Emp> FilteredEmp=empli.stream().filter(agetest.and((genderMtest).or(genderFtest)))
.collect(Collectors.toList());
//printing by consumer
MyConsumer action = new MyConsumer();
FilteredEmp.forEach(action);
}
}
//creation of consumer implementation
class MyConsumer implements Consumer<Emp>{
public void accept(Emp t) {
System.out.println("Consumer impl name of emp ::"+t.getName()+":: with respective gender ::"
+t.getGender());
}
}
Upvotes: 0
Reputation: 6808
I have had a similar question: how to use Java streams to filter a subset of objects that satisfy CONDITION_1 OR CONDITION_2. I figured out it would be to include both conditions in the filter.
myListOfElms().stream()
.filter(elm -> elm.condition1OK() || elm.condition2OK())
.collect(toList());
Of course wrapping these conditions in a private method would make it look better. But that's the idea.
Upvotes: 0
Reputation: 7189
You should create multiple predicates for each condition and join it using or. I have added my below example:
public class MeTest {
Predicate<Integer> con1 = i -> i==0;
Predicate<Integer> con2 = i -> i==1;
Predicate<Integer> con3 = i -> i==2;
@Test
public void testOr() {
List<Integer> asdas = IntStream.range(1, 10).boxed().filter(con1.or(con2).or(con3)).collect(toList());
System.out.println("asdas = " + asdas);
}
}
Upvotes: 26
Reputation: 23352
The first one is incorrect as it has a x ->
too much.
The second one does not filter as you constructed a condition that is always true
. Just refine your condition in the filter
-method and it will filter.
EDIT (as the question got detailed):
I still think, you have an error in your condition. You probably want to exclude both acl1
and acl2
. If so, your condition should rather look something like:
!(x.getAclName().equalsIgnoreCase("acl1") || x.getAclName().equalsIgnoreCase("acl2"))
// or if you prefer &&
!x.getAclName().equalsIgnoreCase("acl1") && !x.getAclName().equalsIgnoreCase("acl2")
// or if you prefer regular expressions/matches
!x.getAclName().matches("(?i)^acl[1|2]$")
Upvotes: 6
Reputation: 45826
items = Arrays.stream(items).filter(
x -> !x.getName().equalsIgnoreCase("redirect")
|| x->!x.getName().equalsIgnoreCase("success"))
.toArray(ItemDetails[]::new);
Note the second x->
. That's used to bind a variable at the start of a lambda. Putting it in the middle is invalid, and unnecessary since x
already exists in the scope. Just remove that bit:
items = Arrays.stream(items).filter(x ->
!x.getName().equalsIgnoreCase("redirect")
|| !x.getName().equalsIgnoreCase("success"))
.toArray(ItemDetails[]::new);
Upvotes: 1