-1
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");
    }
}

When I run this code I want to add all of the image files in a folder (folderPath) to a hashMap with a String of everything before .png as the key. For whatever reason the final array of Strings is somehow having its reference changed and int i is jumping around all over the place. I really have tried and I can't figure this one out. Can anyone explain this to me? My console prints are below. (My code is all in one thread so that is not an issue)

[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

EDIT: I forgot to mention that my code runs normally when it is run in eclipse's debug mode. Here are those results with a break point on the 1st line of the method.

[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

When the thread ID was printed every line I get Thread[Animation Thread,5,main] for every line printed

  • 2
    You're printing `files`, which is a string array, why? – Dave Newton May 17 '18 at 20:38
  • 1
    So you are running this in multiple threads? Because clearly you've got iterations through multiple different arrays jumbled together here. – khelwood May 17 '18 at 20:38
  • 1
    Print your thread ids... because you have at least three arrays with identical values. Look for the text "1stBulletBar, 0" – Elliott Frisch May 17 '18 at 20:39
  • 2
    Can you please post a [mcve]? – Kevin Workman May 17 '18 at 20:40
  • 1
    @khelwood is right, looks like you are running in multiple threads. There is a distorted line in the output which proves multiple threads :) – vkx May 17 '18 at 20:44
  • 1
    After your edit, I can say probably you are running two instances in Eclipse. – vkx May 17 '18 at 20:45
  • There are results from three different threads mixed together, including one torn write where the array id was written, then another thread intervened, and then the rest of the line was written (you really shouldn't break logging across multiple `System.print` calls like that). – David Conrad May 17 '18 at 20:54
  • @vkx I fully restarted eclipse and I still got the same issues. I also just updated my JDK and eclipse yesterday. – Benjamin Leistiko May 17 '18 at 20:55
  • You can update Eclipse and the JDK all you want. It won't help. How and where is this method being called? Is it called in response to some event? Three of them are running simultaneously. – David Conrad May 17 '18 at 20:58
  • @DavidConrad I thought that that could be the case but the thread ID is always the same which leads me to believe it is not the case. Am I missing something else. – Benjamin Leistiko May 17 '18 at 20:58
  • Somehow the threads are being created with the same thread ID, then. The thread name is specified with `Thread::setName`; you could have a thousand threads with the same name. – David Conrad May 17 '18 at 20:59
  • @DavidConrad it is being called in a very unique way. I have a bunch of Scene objects that extend processing's PApplet. There is a boolean in the class this is called from. When a scene is made in processing setup() the method is called. If that boolean is false, this method is called and then the boolean set to true so if another scene attempts to call it nothing should happen. Another thing, the class this is in is stored as a public static field so that could effect things besides being bad style. – Benjamin Leistiko May 17 '18 at 21:03
  • There's your problem. They're racing to call this before the boolean is set (or, before they see the boolean has been set), and currently, three of them are winning the race. – David Conrad May 17 '18 at 21:06
  • @DavidConrad Thank you for the help. That is definitely the case. I asked a friend who knows more about processing and he said he believes every PApplet will make its own thread. I will just have to wait for the first PApplet I make to finish loading and then continue with my code. – Benjamin Leistiko May 17 '18 at 21:08

2 Answers2

1

The data in the question has three different values for the files array, and the counters run from 0 to 24 for each of them. Clearly, three calls to this method are progressing simultaneously in three different threads. From your comment:

I have a bunch of Scene objects that extend processing's PApplet. There is a boolean in the class this is called from. When a scene is made in processing setup() the method is called. If that boolean is false, this method is called and then the boolean set to true so if another scene attempts to call it nothing should happen.

You have a race condition wherein three threads are checking the boolean and calling this method before any of them see that the boolean has been set. How to fix that depends on what the code looks like at the point where that variable is tested and set and the call is made.

David Conrad
  • 15,432
  • 2
  • 42
  • 54
0

You should read this post.

The keyword final simply means you can only initialize the variable once. That does not mean the value can't change. In fact, you can call methods and change the value of a final variable all you want.

I'm suspecting that you are actually changing the value of the variable and not its reference.

Kellen Stuart
  • 7,775
  • 7
  • 59
  • 82
  • Yes I found that when researching stuff but it still doesn't answer why the method is called multiple times? People above are saying multiple threads which I guess makes sense. – Benjamin Leistiko May 17 '18 at 20:48
  • @BenjaminLeistiko I guess my question to you - did you write this threaded? It appears to be a single threaded program from what you wrote in your question – Kellen Stuart May 17 '18 at 20:50
  • I wrote it single threaded. It is a collaboration project so I will talk with the rest of the people working on it this afternoon, but the original vision was to write it all in one thread. When I printed the thread ID's I got this for all of them. Thread[Animation Thread,5,main] – Benjamin Leistiko May 17 '18 at 20:53
  • The value of the array reference never changes during the execution of the method. There are three calls to the method running in parallel, each with its own unique, unchanging reference. – David Conrad May 17 '18 at 20:56