1
\$\begingroup\$

I wrote some Java code to look up all files in a chosen directory (like it's showing in the Windows Explorer), and to display the results, but it seems to be slow. Can you tell me, how to speed up it?

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Objects;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class Main extends SimpleFileVisitor<Path> {
    HashMap<Path, CarsAndSizes> map = new HashMap<>();

    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
        if (!map.containsKey(dir)) {
            map.put(dir, new CarsAndSizes(dir, 0, 0));
        }
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        Path p = file.getParent();
        long a = file.toFile().length();
        while (p != null && map.containsKey(p)) {
            map.get(p).incCar().addSize(a);
            p = p.getParent();
        }
        return FileVisitResult.CONTINUE;
    }

    // If there is some error accessing
    // the file, let the user know.
    // If you don't override this method
    // and an error occurs, an IOException
    // is thrown.
    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) {
        return FileVisitResult.CONTINUE;
    }

    public static void main(String[] args) throws IOException {
        JFileChooser j = new JFileChooser();
        j.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        j.showOpenDialog(null);
        Main m = new Main();
        Files.walkFileTree(j.getSelectedFile().toPath(), m);

        Object[][] oa = new Object[m.map.size()][3];
        int i = 0;
        for (Entry<Path, CarsAndSizes> e : m.map.entrySet()) {
            oa[i][0] = e.getKey().toString();
            oa[i][1] = e.getValue().car;
            oa[i][2] = e.getValue().size;
            i++;
        }
        DefaultTableModel model = new DefaultTableModel(oa, new String[] { "Path", "Cars", "Sizes" }) {
            private static final long serialVersionUID = 1L;

            @SuppressWarnings({ "unchecked", "rawtypes" })
            @Override
            public Class getColumnClass(int column) {
                switch (column) {
                case 0:
                    return String.class;
                case 1:
                    return Integer.class;
                case 2:
                    return Long.class;
                default:
                    return String.class;
                }
            }
        };
        for (int k = model.getRowCount() - 1; k >= 0; k--) {
            if ((Integer) model.getValueAt(k, 1) == 0)
                model.removeRow(k);
        }
        JTable table = new JTable(model);
        JScrollPane scroll = new JScrollPane(table);
        table.setAutoCreateRowSorter(true);
        JFrame frame = new JFrame();
        frame.add(scroll);
        frame.setSize(800, 800);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setVisible(true);
    }
}

class CarsAndSizes implements Comparable<CarsAndSizes> {
    Path p;
    int car;
    long size;

    CarsAndSizes(Path p, int car, long size) {
        super();
        this.p = p;
        this.car = car;
        this.size = size;
    }

    CarsAndSizes incCar() {
        car++;
        return this;
    }

    CarsAndSizes addSize(long a) {
        size += a;
        return this;
    }

    @Override
    public int hashCode() {
        return Objects.hash(p);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        CarsAndSizes other = (CarsAndSizes) obj;
        return Objects.equals(p, other.p);
    }

    @Override
    public int compareTo(CarsAndSizes o) {
        if (car == o.car) {
            if (size == o.size)
                return p.compareTo(o.p);
            else
                return Long.compare(o.size, size);
        }
        return Integer.compare(o.car, car);
    }

    @Override
    public String toString() {
        return String.format("CarsAndSizes [p=%s, car=%10s, size=%10s]", p, car, size);
    }
}
\$\endgroup\$
  • \$\begingroup\$ First step is to put in timers and start pin pointing what exactly is slow. \$\endgroup\$ – Sam Orozco Oct 8 at 3:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.