B4J Question Strange Error with List

Midimaster

Active Member
Licensed User
I tried to help a friend with an File.ListFiles() example and run myself into a strange problem:

Why does this not work?
B4X:
#Region Project Attributes
    #MainFormWidth: 600
    #MainFormHeight: 600
#End Region

Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private xui As XUI
    Private Button1 As B4XView
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("Layout1")
    MainForm.Show
    Check_C
End Sub

Sub Check_C
    Dim Result As List= File.ListFiles("C:\")
    For Each Name As String In Result
        If File.IsDirectory("C:\",Name)=False   Then
            Dim da As Int =Result.IndexOf(Name)
            Result.RemoveAt(da)
        End If
    Next
End Sub

Waiting for debugger to connect...
Program started.
Fehler in Zeile: 25 (Main)
java.lang.UnsupportedOperationException
at java.base/java.util.AbstractList.remove(AbstractList.java:167)
at anywheresoftware.b4a.objects.collections.List.RemoveAt(List.java:92)
at b4j.example.main._check_c(main.java:115)
at b4j.example.main._appstart(main.java:80)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:632)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:237)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:78)
at b4j.example.main.start(main.java:38)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:834)
 
Last edited:

OliverA

Expert
Licensed User
Longtime User
You cannot remove elements of a list while processing it with For/Each. You are pulling the rug from under yourself. Everytime you remove an element in the list, it changes the index position of the rest of the items. You can either use another list to store the elements to be removed and then use that list to remove the elements or you can process your list from the back to the front via indexing.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
The above answer is mostly correct. The actual error happens because it is a read only list:

1602505823801.png
 
Upvote 0

Midimaster

Active Member
Licensed User
Ah! Did not know that. Thank you for the quick response.

But does Removing (in a self build list) really disturb the process during a For Each loop?
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
But does Removing (in a self build list) really disturb the process during a For Each loop?
Yes.

Asuming you are working with a non-readonly list.

You only can prevent it when going from the last item down to the first item. As ALREADY MENTIONED earlier in this thread.

B4X:
for i = list.size-1 to 0 step -1
  ' work here. Even removing is possible,
 next
 
Upvote 0
Top