Iterate on a range of iterable - iterator

I have interface that returns a iterable object.
I need to iterate on the first 1000 items of it.
What is the best way to combine iterating using Iterator and stop after a certain count is reached.
Thanks

I'd use a loop that iterates and have a counter variable incremented; then break out of the loop when the counter reaches 1000.

What is your language?
C#:
using System.Linq;
//...
foreach (var item in iface.GetIterable().Take(1000))
{
//...
}
Python:
import itertools
#...
for item in itertools.islice(iface.get_iterable(), 1000):
#...

Make a standard loop that iterates over your collection, but check to see if the index has progress past the target index.
You may want to extract a seperate counter from the main loop index for your specific application.
int stopIndex = 1000;
for (int index = 0; index <= theInterface.Count; index++)
{
// check to see if we're at/past the stopIndex
if (index >= stopIndex)
break;
// we're still within the conditions, so do something with your interface
myObjectType localObject = (MyObjectType)theInterface.IndexOf(index);
}

Here's a test-driven (Java) wrapper around any existing iterator that should do the trick.
package com.playground;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
public class LimitedIterableTest extends TestCase {
private static class LimitedIterator<T> implements Iterator<T> {
private final Iterator<T> original;
private final int limit;
private int index = 0;
public LimitedIterator(Iterator<T> iterator, int limit) {
this.original = iterator;
this.limit = limit;
}
public boolean hasNext() {
return index < limit && original.hasNext();
}
public T next() {
index++;
return original.next();
}
public void remove() {
original.remove();
}
}
private static class LimitedIterable<T> implements Iterable<T> {
private final int limit;
private final Iterable<T> original;
public LimitedIterable(Iterable<T> iterable, int limit) {
this.original = iterable;
this.limit = limit;
}
public Iterator<T> iterator() {
return new LimitedIterator<T>(original.iterator(), limit);
}
}
final Integer[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
final List<Integer> list = Arrays.asList(array);
public void testCount() throws Exception {
assertEquals(10, count(list));
}
public void testLimitedIterable() throws Exception {
Iterable<Integer> limited = new LimitedIterable<Integer>(list, 5);
assertEquals(5, count(limited));
limited = new LimitedIterable<Integer>(list, 50);
assertEquals(10, count(limited));
}
private static <T> int count(Iterable<T> iterable) {
Iterator<T> iterator = iterable.iterator();
return count(iterator);
}
private static <T> int count(Iterator<T> iterator) {
int count = 0;
while (iterator.hasNext()) {
iterator.next();
count++;
}
return count;
}
}

Related

optaplanner can't get the best solution, and different input orders produce different solutions

I'm trying to make a demo using optaplanner: there are some schemes, each scheme has attribute of gain and cost, and a scheme may conflict with one or more other schemes. The question is to find out a group of schemes which match following constraints:
hard constraint: selected schemea may not conflict with each other in this group
soft constraint: make the difference between total gain and total cost as high as possible
I built following code and try to resolve the question:
#PlanningEntity
#Data
#NoArgsConstructor
public class Scheme {
#PlanningId
private String id;
private int gain;
private int cost;
#PlanningVariable(valueRangeProviderRefs = {"validRange"})
// when valid is ture means this scheme will be selected into the solution group
private Boolean valid;
private Set<String> conflicts = new HashSet<>();
public void addConflict(String id) {
conflicts.add(id);
}
public Scheme(String id, int gain, int cost, String[] conflicts) {
this.id = id;
this.gain = gain;
this.cost = cost;
for (String s : conflicts) {
addConflict(s);
}
}
}
#PlanningSolution
public class SchemeSolution {
private HardSoftScore score;
private List<Scheme> schemeList;
#ProblemFactCollectionProperty
#ValueRangeProvider(id = "validRange")
public List<Boolean> getValidRange() {
return Arrays.asList(Boolean.FALSE, Boolean.TRUE);
}
#PlanningScore
public HardSoftScore getScore() {
return score;
}
public void setScore(HardSoftScore score) {
this.score = score;
}
#PlanningEntityCollectionProperty
public List<Scheme> getSchemeList() {
return schemeList;
}
public void setSchemeList(List<Scheme> schemeList) {
this.schemeList = schemeList;
}
}
And the constraint rule as below:
rule "conflictCheck"
when
Boolean(this==true) from accumulate (
$schs: List() from collect (Scheme(valid==true)),
init(boolean cfl = false;Set cfSet = new HashSet();List ids = new ArrayList()),
action(
for(int i = 0; i < $schs.size(); ++i) {
Scheme sch = (Scheme)$schs.get(i);
cfSet.addAll(sch.getConflicts());
ids.add(sch.getId());
}
for( int i = 0; i < ids.size(); ++i) {
String id = (String)ids.get(i);
if(cfSet.contains(id)) {
cfl = true;
return true;
}
}
),
result(cfl)
)
then
scoreHolder.addHardConstraintMatch(kcontext, -10000);
end
rule "bestGain"
when
$gc : Number() from
accumulate(
Scheme(valid==true, $gain : gain, $cost: cost),
sum($gain - $cost)
)
then
scoreHolder.addSoftConstraintMatch(kcontext, $gc.intValue());
end
Then I constructed three schemes as input of the test. Oddly, I found that optaplanner can't get the best solution, and different input orders produce different solutions.
When I set input as following:
private static List<Scheme> getSchemes() {
List<Scheme> ret = new ArrayList();
ret.add(new Scheme("S1", 5, 2, new String[]{"S3"}));
ret.add(new Scheme("S2", 3, 1, new String[]{"S3"}));
ret.add(new Scheme("S3", 10, 4, new String[]{"S1", "S2"}));
return ret;
}
the output is :
0hard/5soft
Scheme(id=S1, gain=5, cost=2, valid=true, conflicts=[S3])
Scheme(id=S2, gain=3, cost=1, valid=true, conflicts=[S3])
Scheme(id=S3, gain=10, cost=4, valid=false, conflicts=[S1, S2])
And when I set input as following:
private static List<Scheme> getSchemes() {
List<Scheme> ret = new ArrayList();
ret.add(new Scheme("S3", 10, 4, new String[]{"S1", "S2"}));
ret.add(new Scheme("S1", 5, 2, new String[]{"S3"}));
ret.add(new Scheme("S2", 3, 1, new String[]{"S3"}));
return ret;
}
I get the best solution and the output is :
0hard/6soft
Scheme(id=S3, gain=10, cost=4, valid=true, conflicts=[S1, S2])
Scheme(id=S1, gain=5, cost=2, valid=false, conflicts=[S3])
Scheme(id=S2, gain=3, cost=1, valid=false, conflicts=[S3])
Could anyone help me about it?

OptaPlaner simple example cant find feasible solution

to get familiar with optaplanner i created a simple test project. I only have one Solution and one Entity class. The Entity has only one value between 0 and 9. There should only be odd numbers and the sum of all should be less then 10 (this are just some random constraints i came up with).
As Score i use a simple HardSoftScore. Here is the code:
public class TestScoreCalculator implements EasyScoreCalculator<TestSolution>{
#Override
public HardSoftScore calculateScore(TestSolution sol) {
int hardScore = 0;
int softScore = 0;
int valueSum = 0;
for (TestEntity entity : sol.getTestEntities()) {
valueSum += entity.getValue() == null? 0 : entity.getValue();
}
// hard Score
for (TestEntity entity : sol.getTestEntities()) {
if(entity.getValue() == null || entity.getValue() % 2 == 0)
hardScore -= 1; // constraint: only odd numbers
}
if(valueSum > 10)
hardScore -= 2; // constraint: sum should be less than 11
// soft Score
softScore = valueSum; // maximize
return HardSoftScore.valueOf(hardScore, softScore);
}
}
and this is my config file:
<?xml version="1.0" encoding="UTF-8"?>
<solver>
<!-- Domain model configuration -->
<scanAnnotatedClasses/>
<!-- Score configuration -->
<scoreDirectorFactory>
<easyScoreCalculatorClass>score.TestScoreCalculator</easyScoreCalculatorClass>
</scoreDirectorFactory>
<!-- Optimization algorithms configuration -->
<termination>
<secondsSpentLimit>30</secondsSpentLimit>
</termination>
</solver>
for some reason OptaPlanner cant find a feasible solution. It terminates with LS step (161217), time spent (29910), score (-2hard/10soft), best score (-2hard/10soft)... and the solution 9 1 0 0.
So the hardScore is -2 because the two 0 are not odd. A possible solution would be 7 1 1 1 for example. Why is this ? This should be a really easy example ...
(when i set the Start values to 7 1 1 1 it terminates with this solution and a score of (0hard/10soft) how it should be)
Edit:
The Entity class
#PlanningEntity
public class TestEntity {
private Integer value;
#PlanningVariable(valueRangeProviderRefs = {"TestEntityValueRange"})
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
#ValueRangeProvider(id = "TestEntityValueRange")
public CountableValueRange<Integer> getStartPeriodRange() {
return ValueRangeFactory.createIntValueRange(0, 10);
}
}
The Solution class
#PlanningSolution
public class TestSolution {
private List<TestEntity> TestEntities;
private HardSoftScore score;
#PlanningEntityCollectionProperty
public List<TestEntity> getTestEntities() {
return TestEntities;
}
public void setTestEntities(List<TestEntity> testEntities) {
TestEntities = testEntities;
}
#PlanningScore
public HardSoftScore getScore() {
return score;
}
public void setScore(HardSoftScore score) {
this.score = score;
}
#Override
public String toString() {
String str = "";
for (TestEntity testEntity : TestEntities)
str += testEntity.getValue()+" ";
return str;
}
}
The Main Program class
public class Main {
public static final String SOLVER_CONFIG = "score/TestConfig.xml";
public static int printCount = 0;
public static void main(String[] args) {
init();
}
private static void init() {
SolverFactory<TestSolution> solverFactory = SolverFactory.createFromXmlResource(SOLVER_CONFIG);
Solver<TestSolution> solver = solverFactory.buildSolver();
TestSolution model = new TestSolution();
List<TestEntity> list = new ArrayList<TestEntity>();
// list.add(new TestEntity(){{setValue(7);}});
// list.add(new TestEntity(){{setValue(1);}});
// list.add(new TestEntity(){{setValue(1);}});
// list.add(new TestEntity(){{setValue(1);}});
for (int i = 0; i < 4; i++) {
list.add(new TestEntity());
}
model.setTestEntities(list);
// Solve the problem
TestSolution solution = solver.solve(model);
// Display the result
System.out.println(solution);
}
}
It gets stuck in a local optima because there is no move that takes 1 from entity and gives it to another entity. With a custom move you can add that.
These kind of moves only apply to numeric value ranges (which are rare, usually value ranges are a list of employees etc), but they should probably exist out of the box (feel free to create a jira for them).
Anyway, another way to get the good solution is to add <exhaustiveSearch/>, that bypassing local search and therefore the local optima. But that doesn't scale well.

How to deserialize a JSON array to a singly linked list by using Jackson

I want to deserialize a JSON array to a singly linked list in Java.
The definition of singly linked list is as the following:
public class SinglyLinkedListNode<T> {
public T value;
public SinglyLinkedListNode next;
public SinglyLinkedListNode(final T value) {
this.value = value;
}
}
How to deserialize a JSON string such as [1,2,3,4,5] in to a singly linked list?
public void typeReferenceTest() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
final ArrayList<Integer> intArray = objectMapper.readValue("[1,2,3,4,5]",
new TypeReference<ArrayList<Integer>>() {});
System.out.println(intArray);
// How to achieve this?
final ArrayList<Integer> intList = objectMapper.readValue("[1,2,3,4,5]",
new TypeReference<SinglyLinkedListNode<Integer>>() {});
System.out.println(intList);
}
Moreover, I want the SinglyLinkedListNode to be a first-class citizen the same as ArrayList, which can be used in all kinds of combinations, such as HashSet<SinglyLinkedListNode<Integer>>, SinglyLinkedListNode<HashMap<String, Integer>>.
For example, what happens if I want to deserialize [[1,2,3], [4,5,6]] into a ArrayList<SinglyLinkedListNode<Integer>> ?
As far as I know, a customized deserializer extending JsonDeserializer is not enough to do this.
When you want it to be deserialized to ArrayList<SinglyLinkedListNode<Integer>> for example. Your code specifies that is the type that expected. Therefore it should if a deserializer for SinglyLinkedListNode<Integer> is regeistered it will succeed.
From the jackson-user google group I get the right answer from #Tatu Saloranta.
The answer is simple: just implement the java.util.List interface, and Jackson will automatically serialize/deserialize between JSON array and SinglyLinkedListNode.
So I implement the java.util.List interface for SinglyLinkedListNode, the code is as the following:
import java.util.*;
import java.util.function.Consumer;
/**
* Singly Linked List.
*
* <p>As to singly linked list, a node can be viewed as a single node,
* and it can be viewed as a list too.</p>
*
* #param <E> the type of elements held in this collection
* #see java.util.LinkedList
*/
public class SinglyLinkedListNode<E>
extends AbstractSequentialList<E>
implements Cloneable, java.io.Serializable {
public E value;
public SinglyLinkedListNode<E> next;
/**
* Constructs an empty list.
*/
public SinglyLinkedListNode() {
value = null;
next = null;
}
/**
* Constructs an list with one elment.
*/
public SinglyLinkedListNode(final E value) {
this.value = value;
next = null;
}
/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* #param c the collection whose elements are to be placed into this list
* #throws NullPointerException if the specified collection is null
*/
public SinglyLinkedListNode(Collection<? extends E> c) {
this();
addAll(c);
}
/**
* Links e as last element.
*/
void linkLast(E e) {
final SinglyLinkedListNode<E> l = last();
final SinglyLinkedListNode<E> newNode = new SinglyLinkedListNode<>(e);
if (l == null)
this.value = e;
else
l.next = newNode;
modCount++;
}
/**
* Inserts element e before non-null Node succ.
*/
void linkBefore(E e, SinglyLinkedListNode<E> succ) {
assert succ != null;
final SinglyLinkedListNode<E> prev = this.previous(succ);
final SinglyLinkedListNode<E> newNode = new SinglyLinkedListNode<>(e);
if (prev == null)
this.value = e;
else
prev.next = newNode;
modCount++;
}
/**
* Return the node before x.
*
* #param x current node
* #return the node before x
*/
private SinglyLinkedListNode<E> previous(final SinglyLinkedListNode<E> x) {
assert (x != null);
if (size() < 2) return null;
if (this == x) return null;
SinglyLinkedListNode<E> prev = new SinglyLinkedListNode<>();
prev.next = this;
SinglyLinkedListNode<E> cur = this;
while (cur != x) {
prev = prev.next;
cur = cur.next;
}
return prev;
}
/**
* Return the last node.
* #return the last node.
*/
private SinglyLinkedListNode<E> last() {
if (size() == 0) return null;
if (size() == 1) return this;
SinglyLinkedListNode<E> prev = new SinglyLinkedListNode<>();
prev.next = this;
SinglyLinkedListNode<E> cur = this;
while (cur != null) {
prev = prev.next;
cur = cur.next;
}
return prev;
}
/**
* Unlinks non-null node x.
*/
E unlink(SinglyLinkedListNode<E> x) {
assert x != null;
final E element = x.value;
final SinglyLinkedListNode<E> next = x.next;
final SinglyLinkedListNode<E> prev = previous(x);
if (prev == null) {
this.value = next.value;
this.next = next.next;
} else {
prev.next = next;
}
x.next = null;
modCount++;
return element;
}
/**
* #inheritDoc
*/
public ListIterator<E> listIterator(int index) {
checkPositionIndex(index);
return new ListItr(index);
}
private class ListItr implements ListIterator<E> {
private SinglyLinkedListNode<E> lastReturned;
private SinglyLinkedListNode<E> next;
private int nextIndex;
private int expectedModCount = modCount;
ListItr(int index) {
assert isPositionIndex(index);
next = (index == size()) ? null : node(index);
nextIndex = index;
}
public boolean hasNext() {
return nextIndex < size();
}
public E next() {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();
lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.value;
}
public boolean hasPrevious() {
return nextIndex > 0;
}
public E previous() {
throw new UnsupportedOperationException();
}
public int nextIndex() {
return nextIndex;
}
public int previousIndex() {
return nextIndex - 1;
}
public void remove() {
checkForComodification();
if (lastReturned == null)
throw new IllegalStateException();
unlink(lastReturned);
nextIndex--;
lastReturned = null;
expectedModCount++;
}
public void set(E e) {
if (lastReturned == null)
throw new IllegalStateException();
checkForComodification();
lastReturned.value = e;
}
public void add(E e) {
checkForComodification();
lastReturned = null;
if (next == null)
linkLast(e);
else
linkBefore(e, next);
nextIndex++;
expectedModCount++;
}
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (modCount == expectedModCount && nextIndex < size()) {
action.accept(next.value);
lastReturned = next;
next = next.next;
nextIndex++;
}
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
/**
* #inheritDoc
*/
public int size() {
int size = 0;
if (value == null) return size;
SinglyLinkedListNode<E> cur = this;
while (cur != null) {
size++;
cur = cur.next;
}
return size;
}
private void checkPositionIndex(int index) {
if (!isPositionIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/**
* Returns the (non-null) Node at the specified element index.
*/
SinglyLinkedListNode<E> node(int index) {
assert isElementIndex(index);
SinglyLinkedListNode<E> x = this;
for (int i = 0; i < index; i++)
x = x.next;
return x;
}
/**
* Tells if the argument is the index of an existing element.
*/
private boolean isElementIndex(int index) {
return index >= 0 && index < size();
}
/**
* Tells if the argument is the index of a valid position for an
* iterator or an add operation.
*/
private boolean isPositionIndex(int index) {
return index >= 0 && index <= size();
}
/**
* Constructs an IndexOutOfBoundsException detail message.
* Of the many possible refactorings of the error handling code,
* this "outlining" performs best with both server and client VMs.
*/
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: " + size();
}
}
Here is the unit test code:
#Test public void typeReferenceTest() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
final SinglyLinkedListNode<Integer> intList = objectMapper.readValue("[1,2,3,4,5]",
new TypeReference<SinglyLinkedListNode<Integer>>() {});
System.out.println(intList);
final ArrayList<SinglyLinkedListNode<Integer>> arrayOfList = objectMapper.readValue("[[1,2,3], [4,5,6]]",
new TypeReference<ArrayList<SinglyLinkedListNode<Integer>>>() {});
System.out.println(arrayOfList);
}
#Tatu Saloranta Thank you very much!
Here is my original blog, Deserialize a JSON Array to a Singly Linked List

Extract common objects from an arraylist

I have a list like shown below. Assume it has 16 Container objects in it. Each Container object is a simple bean, with fields like age, weight, height, etc. How can I create a sub-list that contains common 'Container' objects if a 'Container' object is considered equal if the weight and height are equal?
List<Container> containers = new ArrayList<Container>();
If by "common" containers you mean duplicating ones, then this code might help you:
import java.util.ArrayList;
import java.util.List;
public class CommonContainers {
public static void main(String[] args) {
List<Container> containers = new ArrayList<Container>(16);
for(int i=0; i<13; i++) {
containers.add(new Container(i, i));
}
//add a few duplicating ones
containers.add(new Container(1,1));
containers.add(new Container(5,5));
containers.add(new Container(6,6));
List<Container> sublist = new ArrayList<Container>();
for (Container c1 : containers) {
for (Container c2 : containers) {
if(c1 != c2 && c1.equals(c2)) {
sublist.add(c1);
}
}
}
for (Container c : sublist) {
System.out.println(c);
}
}
private static class Container {
private int weight;
private int height;
#Override
public String toString() {
return String.format("Container[w=%d,h=%d]", weight, height);
}
public Container(int weight, int height) {
this.weight = weight;
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + height;
result = prime * result + weight;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Container other = (Container) obj;
if (height != other.height)
return false;
if (weight != other.weight)
return false;
return true;
}
}
}
If you mean something else or need clarification, please let me know.
Thanks John Smith for giving direction on this question. I used the iterator instead and was able to make a nice solution to what I was looking for. below is the solution. Note that .equals is overriden for the Containers comparison. The technique I used will take the master list and create a sub-list while removing elements from the parent list at the same time. The solution can be called recursivly until you convert the master list into a subset of lists.
public List<Container> extractCommonSubList(
List<Container> masterContainerList) {
List<Container> subList = new ArrayList<Container>();
ListIterator<Container> iterator = masterContainerList.listIterator();
// get first item from master list and remove from master list
Container firstContainer = iterator.next();
iterator.remove();
// Add first container to sublist
subList.add(firstContainer);
while (iterator.hasNext()) {
Container container = iterator.next();
// Search for matches
if (firstContainer.equals(container)) {
// containers are a match, continue searching for matches
subList.add(container);
iterator.remove();
continue;
} else {
break;
}
}
// return common list
return subList;
}

Adding message to faceContext is not working in Java EE7 run on glassFish?

I am doing the tutorial on Java EE7 that comes with glassFish installation. It is also available here. The code is present in glassFish server installation directory
/glassFish_installation/glassfish4/docs/javaee-tutorial/examples/cdi/guessnumber-cdi.
The code works fine as it is. It currently displays correct! when a user correctly guesses the number but does not display failed at end of the game. so I introduced, just one minor change to display the failed message. I have added comments right above the relevant change in code.
Somehow, this change did not help. That is, the at the end of the game, failed message is not displayed.
But the game works as usual. I would like to know why this did not work and how to correct it?
Thanks
public class UserNumberBean implements Serializable {
private static final long serialVersionUID = -7698506329160109476L;
private int number;
private Integer userNumber;
private int minimum;
private int remainingGuesses;
#Inject
#MaxNumber
private int maxNumber;
private int maximum;
#Inject
#Random
Instance<Integer> randomInt;
public UserNumberBean() {
}
public int getNumber() {
return number;
}
public void setUserNumber(Integer user_number) {
userNumber = user_number;
}
public Integer getUserNumber() {
return userNumber;
}
public int getMaximum() {
return (this.maximum);
}
public void setMaximum(int maximum) {
this.maximum = maximum;
}
public int getMinimum() {
return (this.minimum);
}
public void setMinimum(int minimum) {
this.minimum = minimum;
}
public int getRemainingGuesses() {
return remainingGuesses;
}
public String check() throws InterruptedException {
if (userNumber > number) {
maximum = userNumber - 1;
}
if (userNumber < number) {
minimum = userNumber + 1;
}
if (userNumber == number) {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("Correct!"));
}
//if remainingGuesses is less than or equal to zero, display failed message
//-----------------------------------------------
if (remainingGuesses-- <= 0) {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("failed "));
}
return null;
}
#PostConstruct
public void reset() {
this.minimum = 0;
this.userNumber = 0;
this.remainingGuesses = 10;
this.maximum = maxNumber;
this.number = randomInt.get();
}
public void validateNumberRange(FacesContext context,
UIComponent toValidate,
Object value) {
int input = (Integer) value;
if (input < minimum || input > maximum) {
((UIInput) toValidate).setValid(false);
FacesMessage message = new FacesMessage("Invalid guess");
context.addMessage(toValidate.getClientId(context), message);
}
}
}
Adding the FacesMessage is actually working, the problem is that you are using postdecrement in your condition.
Postdecrement, as the name suggests, is decremented AFTER the execution of the statement containing the postdecrement.
That means, if you write:
if (remainingGuesses-- <= 0) {
the var remainingGuesses is decremented after the if-condition was evaluated.
In your case, when the last guess is checked, remainingGuesses is actually 1 and therefore the if-condition is not true and the message is not added.
Different obvious solutions:
if (remainingGuesses-- <= 1) {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("failed "));
}
or
if (--remainingGuesses <= 0) {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("failed "));
}
or
remainingGuesses--;
if (remainingGuesses <= 0) {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("failed "));
}
See also:
Is there a difference between x++ and ++x in java?
Difference between i++ and ++i in a loop?