Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Shuffle an array 1

Status
Not open for further replies.

GiffordS

Programmer
May 31, 2001
194
CA
Still just learning java and I have a bit of a newbie question. I'm working with arrays and trying to learn how to sort / shuffle them. I picked up a piece of old code that I had that generated a list of files in a directory and now I want to be able to randomize that list and print the file names in the new random order. I've got no problem creating an array of the file names, and the printing should be fine, but I'm struggling with the randomization part. The closest thing to what I want is shuffle(), but that's for a list not an array. I'll post the relevant code below and welcome any input.

Code:
class Fiel
{
    String path="c:\\ren\\";
    File theFile;
    byte[] data;
    public void genList() throws IOException
     {
        File dir = new File(path);
        File[] list = dir.listFiles();
        File targ = new File(path, "0.txt");
        Collections.shuffle(list);
        byte[] piped;
        FileOutputStream fos = new FileOutputStream(targ);
        
        for(int i=0;i<list.length;i++)
            {
            File current=list[i];
            String fname = current.getName();
            String topipe = new String(fname + "/nl");
            piped = topipe.getBytes();
                        
            try
            {
                fos.write(piped);
            }
            catch(IOException e)
            {
                System.out.println("IOException " + e.getMessage());
                e.printStackTrace();
            }
        }
        fos.flush();
        fos.close();
    }
}

shuffle() obviously isn't the answer, but I can't find anything like it for arrays.
 
Well - don't use arrays because you're not used to other collection classes.
They contain a lot of useful stuff so investing in your knowledge about them will pay back soon.
Code:
 File [] fa = dir.listFiles ();
		File targ = new File (path, "0.txt");
		List <File> al = new ArrayList <File> (fa.length);
		al = Arrays.asList (fa);
		Collections.shuffle (al);
		
		byte [] piped;
		FileOutputStream fos = new FileOutputStream (targ);
		
		for (File current : al)
		{
			String fname = current.getName ();
			String topipe = new String (fname + "\n");
\n or /nl? Netherlands?

seeking a job as java-programmer in Berlin:
 
Stefan,

Thanks for your help but I'm wondering if you could indulge me a few questions. I was playing with something similar to this right after I posted the question, but ran into a few snags. For starters, I definitely took the long route in that I made the ArrayList of String objects rather than File objects, but for what I was doing that didn't matter. Then, I iterated through the File Array, took each name as a String and added them one by one to the ArrayList. Your way is much faster. The problem that I ran into was that I couldn't figure out how to iterate the ArrayList. This line of code...

Code:
for (File current : al)

works well but I don't really understand it. I mean, I understand all of it except the ":". It looks as though this expression is an iterator of a sort, but what does it actually mean. I don't see it referrence under the ArrayList docs on java.sun.com.

Also, while everything I have now works it's still not quite right. Specifically, I cannot close my output stream. I originally posted

Code:
try
            {
                fos.write(piped);
            }
            catch(IOException e)
            {
                System.out.println("IOException " + e.getMessage());
                e.printStackTrace();
            }
        }
        fos.flush();
        fos.close();
    }

but this will not compile as I get an IOException must be caught error. I've tried juggling things around...

Code:
try
            {
                fos.write(piped);
                fos.flush();
                fos.close();
            }
            catch(IOException e)
            {
                System.out.println("IOException " + e.getMessage());
                e.printStackTrace();
            }
        }
        fos.flush();
        fos.close();
    }

but this doesn't work as I am closing my output stream and then have no way to re-open it when the next iteration comes along. The end result is that I get one file listed in my .txt file and then I throw FileNotFound errors. How I ended up was...

Code:
try
            {
                fos.write(piped);
                fos.flush();
            }
            catch(IOException e)
            {
                System.out.println("IOException " + e.getMessage());
                e.printStackTrace();
            }
        }
       }
This works but does not close my output stream. The only other way I can think of to manage this is to put the flush() and close() in it's own try / catch block after the for{} block is completed and the file is written. This seems like it would work but also appears to be a waste of code. Any thoughts?
 
a) The colon can be read as 'in'.
for (a : list) :=> for a in list.

It was introduced with Java-1.5
file:///$JAVA_HOME/docs/guide/language/foreach.html
(or, if not using linux:)
file:///%JAVA_HOME%/docs/guide/language/foreach.html

b) Two try-catch-blocks is the way to go.
I wouldn't call it a waste of code, if you can't achieve the same result with less code.

seeking a job as java-programmer in Berlin:
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top