Reputation: 65
I want to use the filter in a stream only if a checkbox is selected or on an selected index > 1 In the example below there is only 1 filter but I want to use more than one. Is it possible to implement an if condition ?
List<SoeEntry> sortedList = soeArraylist.stream()
.filter(p -> p.getEntryDoy().equals(comboBoxDoys.getSelectedItem()))
.sorted(
Comparator
.comparing(SoeEntry::getEntryGSAT)
.thenComparing(SoeEntry::getEntryNumber)
)
.collect(Collectors.toList());
sortedList.forEach(System.out::println);
Something like
if(comboBox1.getSelectedIndex() > 1) {.filter(p -> p.getEntryDoy().equals(comboBox1.getSelectedItem()))}
if(comboBox2.getSelectedIndex() > 1) {.filter(p -> p.getEntryGSAT().equals(comboBox2.getSelectedItem()))}
if(comboBox3.getSelectedIndex() > 1) {.filter(p -> p.getEntryDuration().equals(comboBox3.getSelectedItem()))}
EDIT: I will try to explain it again. Lets say I have 3 ComboBoxes with items. One ComboBox for DOY, one for GSAT and one for DURATION.
I want wo filter with 0 up to 3 filter. If I select the DOY 025 I want to see only the entries from DOY 025, if I select additionally the GSAT XYZ I want to see the entries from DOY 025 with GSAT XYZ only. If I select additionally a DURATION of 30 I want to see the entries from DOY 025 with GSAT XYZ and a DURATION of 30 only.
Upvotes: 1
Views: 5098
Reputation: 65
Finally I found a solution with a combination of your input.
Stream<SoeEntry> stream = soeArraylist.stream();
List<Predicate<SoeEntry>> allPredicates = new ArrayList<Predicate<SoeEntry>>();
if(comboBoxDoys.getItemCount() > 0 && comboBoxDoys.getSelectedIndex() > 1) stream = stream.filter(p -> p.getEntryDoy().equals(comboBoxDoys.getSelectedItem()));
if(comboBoxSoeSC.getItemCount() > 0 && comboBoxSoeSC.getSelectedIndex() > 1) stream = stream.filter(p -> p.getEntryGSAT().contains(comboBoxSoeSC.getSelectedItem().toString()));
if(!chckbxTTCF1.isSelected() && !chckbxTTCF2.isSelected() && !chckbxTTCF3.isSelected() && !chckbxTTCF4.isSelected() && !chckbxTTCF5.isSelected() && !chckbxTTCF6.isSelected()) {
//allPredicates.add(p -> p.getEntryNumber() > 0);
} else {
if(chckbxTTCF1.isSelected()) allPredicates.add(p -> p.getEntryTTCF1().contains(getScHex(comboBoxSoeSC.getSelectedItem().toString()).getScGSAT()));
if(chckbxTTCF2.isSelected()) allPredicates.add(p -> p.getEntryTTCF2().contains(getScHex(comboBoxSoeSC.getSelectedItem().toString()).getScGSAT()));
if(chckbxTTCF3.isSelected()) allPredicates.add(p -> p.getEntryTTCF3().contains(getScHex(comboBoxSoeSC.getSelectedItem().toString()).getScGSAT()));
if(chckbxTTCF4.isSelected()) allPredicates.add(p -> p.getEntryTTCF4().contains(getScHex(comboBoxSoeSC.getSelectedItem().toString()).getScGSAT()));
if(chckbxTTCF5.isSelected()) allPredicates.add(p -> p.getEntryTTCF5().contains(getScHex(comboBoxSoeSC.getSelectedItem().toString()).getScGSAT()));
if(chckbxTTCF6.isSelected()) allPredicates.add(p -> p.getEntryTTCF6().contains(getScHex(comboBoxSoeSC.getSelectedItem().toString()).getScGSAT()));
stream = stream.filter(allPredicates.stream().reduce(x->false, Predicate::or));
}
List<SoeEntry> sortedList = stream
.sorted(
Comparator
.comparing(SoeEntry::getEntryNumber)
// .thenComparing(SoeEntry::getEntryNumber)
)
.collect(Collectors.toList());
//System.out.println(sortedList);
sortedList.forEach(System.out::println);
Many thx to all :)
Upvotes: 0
Reputation: 265151
Streams themselves are only a description of the action to perform when being collected and are immutable. Each method on Stream
returns a new instance. It is kind of like a Builder (e.g. StringBuilder).
Stream<SoeEntry> stream = soeArraylist.stream();
if(comboBox1.getSelectedIndex() > 1) {
stream = stream.filter(p -> p.getEntryDoy().equals(comboBox1.getSelectedItem()));
} else if(comboBox2.getSelectedIndex() > 1) {
stream = stream.filter(p -> p.getEntryDoy().equals(comboBox2.getSelectedItem()));
} else if(comboBox3.getSelectedIndex() > 1) {
stream = stream.filter(p -> p.getEntryDoy().equals(comboBox3.getSelectedItem()));
}
List<SoeEntry> sortedList = stream
.sorted(
Comparator
.comparing(SoeEntry::getEntryGSAT)
.thenComparing(SoeEntry::getEntryNumber)
))
.collect(Collectors.toList());
System.out.println(sortedList);
Alternatively, compute the predicate before and then use it in your stream:
Predicate<SoeEntry> predicate;
if(comboBox1.getSelectedIndex() > 1) {
predicate = p -> p.getEntryDoy().equals(comboBox1.getSelectedItem());
} else if(comboBox2.getSelectedIndex() > 1) {
predicate = p -> p.getEntryDoy().equals(comboBox2.getSelectedItem());
} else if(comboBox3.getSelectedIndex() > 1) {
predicate = p -> p.getEntryDoy().equals(comboBox3.getSelectedItem());
} else {
predicate = p -> true;
}
List<SoeEntry> sortedList = stream
.filter(predicate)
.sorted(
Comparator
.comparing(SoeEntry::getEntryGSAT)
.thenComparing(SoeEntry::getEntryNumber)
))
.collect(Collectors.toList());
System.out.println(sortedList);
Upvotes: 2
Reputation: 44368
You can first process the comboboxes (assuming the object Combobox
) to create a chain of predicates (Stream<Predicate<SoeEntry>>
) which can be packed into a single Predicate<SoeEntry>
using logical AND with Predicate#and
method:
static Predicate<SoeEntry> comboboxPredicate(Combobox... comboboxes) {
return Arrays.stream(comboboxes)
.filter(combobox -> combobox.getSelectedIndex() > 1)
.map(combobox -> (Predicate<SoeEntry>) soeEntry -> soeEntry
.getEntryDay()
.equals(combobox.getSelectedItem()))
.reduce(Predicate::and)
.orElseGet(() -> soeEntry -> true); // "no" filter by default
}
This can be easily applied:
Predicate<SoeEntry> predicate = comboboxPredicate(combobox1, combobox2, combobox3);
List<SoeEntry> sortedList = soeArraylist.stream()
.filter(predicate)
.sorted(Comparator.comparing(SoeEntry::getEntryGSAT)
.thenComparing(SoeEntry::getEntryNumber))
.collect(Collectors.toList());
Upvotes: 0