Ссылка на конечную переменную, которая изменяется в цикле - PullRequest
0 голосов
/ 17 мая 2018
private void loadFromFolder(String folderPath, PApplet loader) {
    File folder = new File(folderPath);
    final String[] files = folder.list();
    for(int i = 0; i < files.length; i++) {
        String filePath = files[i].substring(0, files[i].indexOf("."));
        images.put(filePath, loader.loadImage(folderPath+fileSeparator+files[i]));
        System.out.print(files);
        System.out.print(": " + filePath + ", " + i + "\n");
    }
}

Когда я запускаю этот код, я хочу добавить все файлы изображений в папке (folderPath) в hashMap со строкой всего до .png в качестве ключа.По какой-то причине окончательный массив Strings каким-то образом изменяет свою ссылку, и int i прыгает повсюду.Я действительно пытался, и я не могу понять это.Кто-нибудь может мне это объяснить?Мои распечатки консоли ниже.(Мой код весь в одном потоке, так что это не проблема)

[Ljava.lang.String;@3d207c96: 1stBulletBar, 0
[Ljava.lang.String;@3d207c96: 1stEmptyBar, 1
[Ljava.lang.String;@3d207c96: 1stHealthBar, 2
[Ljava.lang.String;@3d207c96: 1stStaminaBar, 3
[Ljava.lang.String;@246ef213: 1stBulletBar, 0
[Ljava.lang.String;@3d207c96: BulletBar, 4
[Ljava.lang.String;@3d207c96: BulletBarCap, 5
[Ljava.lang.String;@246ef213: 1stEmptyBar, 1
[Ljava.lang.String;@3d207c96: Button, 6
[Ljava.lang.String;@246ef213: 1stHealthBar, 2
[Ljava.lang.String;@3d207c96: ButtonLeft, 7
[Ljava.lang.String;@246ef213: 1stStaminaBar, 3
[Ljava.lang.String;@3d207c96: ButtonLeftPressed, 8
[Ljava.lang.String;@246ef213: BulletBar, 4
[Ljava.lang.String;@246ef213: BulletBarCap, 5
[Ljava.lang.String;@3d207c96: ButtonPressed, 9
[Ljava.lang.String;@246ef213: Button, 6
[Ljava.lang.String;@246ef213: ButtonLeft, 7
[Ljava.lang.String;@3d207c96: ButtonRight, 10
[Ljava.lang.String;@246ef213: ButtonLeftPressed, 8
[Ljava.lang.String;@246ef213: ButtonPressed, 9
[Ljava.lang.String;@3d207c96: ButtonRightPressed, 11
[Ljava.lang.String;@246ef213: ButtonRight, 10
[Ljava.lang.String;@3d207c96: EmptyBar, 12
[Ljava.lang.String;@246ef213: ButtonRightPressed, 11
[Ljava.lang.String;@1e172402: 1stBulletBar, 0
[Ljava.lang.String;@3d207c96: FirstInventoryPiece, 13
[Ljava.lang.String;@246ef213: EmptyBar, 12
[Ljava.lang.String;@1e172402: 1stEmptyBar, 1
[Ljava.lang.String;@3d207c96: HealthBar, 14
[Ljava.lang.String;@246ef213: FirstInventoryPiece, 13
[Ljava.lang.String;@3d207c96: HealthBarCap, 15
[Ljava.lang.String;@1e172402: 1stHealthBar, 2
[Ljava.lang.String;@246ef213: HealthBar, 14
[Ljava.lang.String;@1e172402: 1stStaminaBar, 3
[Ljava.lang.String;@3d207c96: HUD, 16
[Ljava.lang.String;@246ef213: HealthBarCap, 15
[Ljava.lang.String;@1e172402: BulletBar, 4
[Ljava.lang.String;@3d207c96: InventoryCap, 17
[Ljava.lang.String;@1e172402: BulletBarCap, 5
[Ljava.lang.String;@246ef213: HUD, 16
[Ljava.lang.String;@3d207c96[Ljava.lang.String;@1e172402: Button, 6
: InventoryPiece, 18
[Ljava.lang.String;@1e172402: ButtonLeft, 7
[Ljava.lang.String;@246ef213: InventoryCap, 17
[Ljava.lang.String;@3d207c96: StaminaBar, 19
[Ljava.lang.String;@1e172402: ButtonLeftPressed, 8
[Ljava.lang.String;@3d207c96: StaminaBarCap, 20
[Ljava.lang.String;@246ef213: InventoryPiece, 18
[Ljava.lang.String;@1e172402: ButtonPressed, 9
[Ljava.lang.String;@3d207c96: Title, 21
[Ljava.lang.String;@246ef213: StaminaBar, 19
[Ljava.lang.String;@1e172402: ButtonRight, 10
[Ljava.lang.String;@3d207c96: TitleLeft, 22
[Ljava.lang.String;@246ef213: StaminaBarCap, 20
[Ljava.lang.String;@1e172402: ButtonRightPressed, 11
[Ljava.lang.String;@246ef213: Title, 21
[Ljava.lang.String;@3d207c96: TitleRight, 23
[Ljava.lang.String;@246ef213: TitleLeft, 22
[Ljava.lang.String;@1e172402: EmptyBar, 12
[Ljava.lang.String;@246ef213: TitleRight, 23
[Ljava.lang.String;@1e172402: FirstInventoryPiece, 13
[Ljava.lang.String;@1e172402: HealthBar, 14
[Ljava.lang.String;@1e172402: HealthBarCap, 15
[Ljava.lang.String;@246ef213: ui_big_pieces, 24
[Ljava.lang.String;@3d207c96: ui_big_pieces, 24
[Ljava.lang.String;@1e172402: HUD, 16
[Ljava.lang.String;@1e172402: InventoryCap, 17
[Ljava.lang.String;@1e172402: InventoryPiece, 18
[Ljava.lang.String;@1e172402: StaminaBar, 19
[Ljava.lang.String;@1e172402: StaminaBarCap, 20
[Ljava.lang.String;@1e172402: Title, 21
[Ljava.lang.String;@1e172402: TitleLeft, 22
[Ljava.lang.String;@1e172402: TitleRight, 23
[Ljava.lang.String;@1e172402: ui_big_pieces, 24

РЕДАКТИРОВАТЬ: я забыл упомянуть, что мой код работает нормально, когда он выполняется в режиме отладки Eclipse.Вот результаты с точкой останова в 1-й строке метода.

[Ljava.lang.String;@6e9cfc2e: 1stBulletBar, 0
[Ljava.lang.String;@6e9cfc2e: 1stEmptyBar, 1
[Ljava.lang.String;@6e9cfc2e: 1stHealthBar, 2
[Ljava.lang.String;@6e9cfc2e: 1stStaminaBar, 3
[Ljava.lang.String;@6e9cfc2e: BulletBar, 4
[Ljava.lang.String;@6e9cfc2e: BulletBarCap, 5
[Ljava.lang.String;@6e9cfc2e: Button, 6
[Ljava.lang.String;@6e9cfc2e: ButtonLeft, 7
[Ljava.lang.String;@6e9cfc2e: ButtonLeftPressed, 8
[Ljava.lang.String;@6e9cfc2e: ButtonPressed, 9
[Ljava.lang.String;@6e9cfc2e: ButtonRight, 10
[Ljava.lang.String;@6e9cfc2e: ButtonRightPressed, 11
[Ljava.lang.String;@6e9cfc2e: EmptyBar, 12
[Ljava.lang.String;@6e9cfc2e: FirstInventoryPiece, 13
[Ljava.lang.String;@6e9cfc2e: HealthBar, 14
[Ljava.lang.String;@6e9cfc2e: HealthBarCap, 15
[Ljava.lang.String;@6e9cfc2e: HUD, 16
[Ljava.lang.String;@6e9cfc2e: InventoryCap, 17
[Ljava.lang.String;@6e9cfc2e: InventoryPiece, 18
[Ljava.lang.String;@6e9cfc2e: StaminaBar, 19
[Ljava.lang.String;@6e9cfc2e: StaminaBarCap, 20
[Ljava.lang.String;@6e9cfc2e: Title, 21
[Ljava.lang.String;@6e9cfc2e: TitleLeft, 22
[Ljava.lang.String;@6e9cfc2e: TitleRight, 23
[Ljava.lang.String;@6e9cfc2e: ui_big_pieces, 24

Когда идентификатор строки печатался в каждой строке, я получал Thread [Animation Thread, 5, main] для каждой напечатанной строки

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Данные в вопросе имеют три различных значения для массива files, и для каждого из них счетчики работают от 0 до 24.Очевидно, что три вызова этого метода выполняются одновременно в трех разных потоках.Из вашего комментария:

У меня есть куча объектов Scene, которые расширяют PApplet обработки.В классе есть логическое значение, из которого он вызывается.Когда сцена выполняется в обработке setup (), вызывается метод.Если это логическое значение false, этот метод вызывается, а затем логическое значение устанавливается на true, поэтому, если другая сцена пытается вызвать его, ничего не произойдет.

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

0 голосов
/ 17 мая 2018

Вы должны прочитать это сообщение .

Ключевое слово final просто означает, что вы можете инициализировать переменную только один раз.Это не означает , что значение не может измениться.Фактически, вы можете вызывать методы и изменять значение переменной final сколько хотите.

Я подозреваю, что вы на самом деле изменяете значение переменной, а не ее ссылку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...