Досрочное завершение цикла while

У меня есть задача, которая производит блины, и пользователи могут одновременно их есть. Условие состоит в том, что за 30 секунд можно приготовить всего 12 блинов. Проблема, с которой я столкнулся, заключается в том, что по мере создания блина пользователи едят его, как и ожидалось, но когда он производит последний блин (т. е. 12-й), он завершается, а пользователь не съедает его, в результате чего 1 блин теряется. Мой окончательный результат таков:

Total number of cake produced is 12
Total number of cake eaten is 11
Total number of pancake remained is 1
public class PanCakeTask {

    int consumedPancake;
    int availablePancake;
    int totalPancakeProduced;
    List<String> usersList = new ArrayList<>();

     void producePancake(HashMap<String,Integer>users){

          consumedPancake =0;
          availablePancake = 0;
          totalPancakeProduced = 0;

        if ( totalPancakeProduced <12) {

            for (String user: users.keySet()){
                consumedPancake +=users.get(user);
            }

            //only continue with the production of pancakes if the number of pancakes
            //produced has not exceeded the quota that was given (i.e 12)

            System.out.println("Pancake produced");
            //increment the number of pancakes available
            availablePancake +=1;
            totalPancakeProduced = consumedPancake + availablePancake;

            eatPancake(users);

        }
    }
     void eatPancake(HashMap<String,Integer>users){
         if (usersList.size()>=1){
             System.out.println("The list is "+usersList);
             //first pick the user at random
             Collections.shuffle(usersList)

             int numberEaten = users.get(usersList.get(0));
             
             //get the user that is on index zero after the list has been shuffled
             //then check how many pancake that the picked user has eaten
             //because each user is expected to eat a maximum of 5 pancake

             if (numberEaten >=5){
                 //This means that this user has exhausted his/her quota so he/she cannot
                 //be allowed to eat again
                 //In this case, the eatPancake method is called again to randomly pick another user
                 //I am thinking of removing the user from the list here so that he/she cannot be picked again
                 usersList.remove(0);
                 eatPancake(users);
             }else {
                 //Meaning that the user still has some quota left for him/her to eat
                 //In this other condition, it will check if there is an available pancake produced

                 if (availablePancake >=1){
                     //user will now eat the pancake
                     //then increment the number of pancake eaten by that user
                     // and decrement the number of pancakes available

                     int newCount = numberEaten + 1;
                     availablePancake -=1;

                     //finally update the user that just eaten the pancake
                     users.put(usersList.get(0),newCount);
                 }
             }
         }
    }
    public void performTask(){

        //Hashmap is used to store the users because of key-value pairs
        HashMap <String,Integer> users = new HashMap<>();
        users.put("user1",0);
        users.put("user2",0);
        users.put("user3",0);

        usersList.addAll(users.keySet());

        System.out.println(users);
        System.out.println(usersList);


        //This task can only be executed in 20 seconds

        Instant stop = Instant.now().plusSeconds(20);
        System.out.println("The starting time is "+Instant.now());

        while (stop.isAfter(Instant.now())){
            //only continue the process if it has not exceeded 20 seconds

            if (totalPancakeProduced <12){
                producePancake(users);
            }else {
                break;
            }
        }
        int available = totalPancakeProduced - consumedPancake;
        int numbersLeftToMeetTheDemand = totalPancakeProduced - 15;
        System.out.println("The ending time is "+Instant.now());
        System.out.println("Total number of cake produced is "+totalPancakeProduced);
        System.out.println("Total number of cake eaten is "+consumedPancake);
        System.out.println("Total number of pancake remained is "+available);
                
}

не могли бы вы опубликовать только соответствующий код? минимальный воспроизводимый пример должен подойти

Stultuske 11.07.2024 11:48

Я удалил некоторые операторы печати для удобства чтения и использовал их в целях отладки. Пожалуйста, посмотрите еще раз @Stultuske

Ukeme Elijah 11.07.2024 12:03

вы спрашиваете о поведении цикла while. Во всем остальном коде нет реальной необходимости.

Stultuske 11.07.2024 12:05

Я знаю, я вставил код, чтобы он мог объяснить, что я пытаюсь решить, а также проблему, возникшую при попытке ее решения.

Ukeme Elijah 11.07.2024 12:07

Я вызвал метод eatPancake в операторе else один раз перед оператором Break, чтобы последний созданный блин можно было съесть до завершения, но он все еще не работал.

Ukeme Elijah 11.07.2024 12:10

можешь показать еще журнал печати? например, с 11 блинов и до конца?

Sither Tsering 11.07.2024 12:12

Журнал заканчивается на 11-м блине. это означает, что съедено всего 11 блинов, а приготовлено 12 блинов. Произошло следующее: как только 12-й блин создан и затем проверено, что условие выполнено, он переходит к оператору Break в другой части и завершается без выполнения метода eatPancake, чтобы можно было съесть последний созданный 12-й блин.

Ukeme Elijah 11.07.2024 12:21

я думаю, ты запутался. Ваш метод eatPancake вызывается внутри метода producePancake. Итак, после создания 12-го блина он не возвращается к циклу while, а вызывает метод eatPancake.

Sither Tsering 11.07.2024 12:29

Да, он вызывается внутри метода ProducePancake. Вопрос в том, почему он не вызывает его снова после производства последнего блина. Мне нужна помощь, где его разместить, чтобы его можно было снова вызвать сразу же, как будет изготовлен последний блин.

Ukeme Elijah 11.07.2024 12:42

поэтому и прошу логи, чтобы посмотреть поток. Просто поделитесь ЖУРНАЛАМИ.

Sither Tsering 11.07.2024 12:50
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
10
76
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы обновляете consumedPancake только внутри метода producePancake.

Это станет проблемой, когда ваш цикл достигнет последней итерации. Потому что producePancake рассчитает consumedPancake на основе карты users. После этого вызывается eatPancake, который обновляет карту. Это приведет к неправильному количеству съеденных блинов, поскольку consumedPancake не обновляется снова после eatPancake в последней итерации.

Чтобы исправить это, вместо изменения consumedPancake в методе producePancake увеличьте его в методе eatPancake после того, как блин будет съеден.

Так:

    void eatPancake(HashMap<String,Integer>users){
         if (usersList.size()>=1){
             System.out.println("The list is "+usersList);
             //first pick the user at random
             Collections.shuffle(usersList)

             int numberEaten = users.get(usersList.get(0));
             
             //get the user that is on index zero after the list has been shuffled
             //then check how many pancake that the picked user has eaten
             //because each user is expected to eat a maximum of 5 pancake

             if (numberEaten >=5){
                 //This means that this user has exhausted his/her quota so he/she cannot
                 //be allowed to eat again
                 //In this case, the eatPancake method is called again to randomly pick another user
                 //I am thinking of removing the user from the list here so that he/she cannot be picked again
                 usersList.remove(0);
                 eatPancake(users);
             }else {
                 //Meaning that the user still has some quota left for him/her to eat
                 //In this other condition, it will check if there is an available pancake produced

                 if (availablePancake >=1){
                     //user will now eat the pancake
                     //then increment the number of pancake eaten by that user
                     // and decrement the number of pancakes available

                     int newCount = numberEaten + 1;
                     availablePancake -=1;
                     //finally update the user that just eaten the pancake
                     users.put(usersList.get(0),newCount);
                     //here
                     consumedPancake++;
                 }
             }
         }
    }

amd удалить из ProducePancake:

void producePancake(HashMap<String,Integer>users){

          //consumedPancake =0;
          availablePancake = 0;
          totalPancakeProduced = 0;

        if ( totalPancakeProduced <12) {
            /*
            for (String user: users.keySet()){
                consumedPancake +=users.get(user);
            }
            */

            //only continue with the production of pancakes if the number of pancakes
            //produced has not exceeded the quota that was given (i.e 12)

            System.out.println("Pancake produced");
            //increment the number of pancakes available
            availablePancake +=1;
            totalPancakeProduced = consumedPancake + availablePancake;

            eatPancake(users);

        }
    }

Кроме того, в вашем коде есть некоторые избыточные части, но, похоже, это не является причиной проблемы, поэтому их проигнорировали.

Другие вопросы по теме