How do I manipulate the order of the files in an ArrayList?

1

I'm developing a program, in which part of the processes requires that I take the numbering of the last file listed within a ArrayList .

My question is this, when my ArrayList starts adding the files listed in the directory it adds the files correctly in the sequence of items inside the array, but when it arrives at the file of number 9 the array replaces the first file of the sequence by 10, and only recognizes the number 1 of the complete 10. How do I make the array recognize the 10 as a number that comes after 9?

    
asked by anonymous 17.12.2016 / 15:43

2 answers

1

Idea of solution

First, you have to see that the file names have the prefix + suffix format, where the suffix is a number. With this, we can orgazinar your files, ordering them first by the prefix and then by the suffix.

Implementing the solution

As such, you will need a function that knows how to sort the file names correctly. Here's one:

public static int comparaNomesDeArquivos(String nome1, String nome2) {
    if (Objects.equals(nome1, nome2)) return 0;
    if (nome1 == null) return -1;
    if (nome2 == null) return 1;

    int sufixo1 = 0, sufixo2 = 0;
    int n;
    int p = 1;
    for (n = nome1.length() - 1; n >= 0; n--) {
        char c = nome1.charAt(n);
        if (c < '0' || c > '9') break;
        sufixo1 += (c - '0') * p;
        p *= 10;
    }
    p = 1;
    String prefixo1 = nome1.substring(0, n + 1);
    for (n = nome2.length() - 1; n >= 0; n--) {
        char c = nome2.charAt(n);
        if (c < '0' || c > '9') break;
        sufixo2 += (c - '0') * p;
        p *= 10;
    }
    String prefixo2 = nome2.substring(0, n + 1);
    int a = prefixo1.compareTo(prefixo2);
    if (a != 0) return a;
    int b = sufixo1 - sufixo2;
    if (b != 0) return b;
    return nome1.compareTo(nome2);
}

The explanation of this function is as follows:

  • Like any comparison function in Java , it has as parameter two elements to be compared. Returns a positive number if the first element is after the second, negative if it is before, or zero if both are the same.

  • For the sake of optimization, we first check whether% w and% w are identical, and in this case we know that they are equal. This case is determined with String ". This check also works if both Objects.equals(Object, Object) s is String .

  • If one of the null s is String (and it is already known that only one of them could be because the case where the two are is treated in step 2), then consider that null precedes any else, returning -1 or 1 in these cases.

  • To separate the suffix prefix, this function traverses each back-to-front string for the purpose of determining them. For this, a null loop is used for each.

  • If the prefix of for s is different, then the ordering is given by the prefix.

  • Since the prefixes are the same, then the ordering is given by the suffix, which is a number.

  • Since prefixes and suffixes are the same, what can happen if you compare String with batatinha123 , that is, when the difference is only for the zeros to the left of the number, then it uses the form of standard comparison.

  • Knowing how to compare% s with% s, you can set up a function to compare files. I do not know exactly how you're repressing a file. If it goes directly by their names, then you can skip this part. Otherwise, assuming the batatinha0123 method is what determines the filename, do this:

    public static int comparaArquivosPorNome(Arquivo arquivo1, Arquivo arquivo2) {
        String nome1 = arquivo1 == null ? null : arquivo1.getFilename();
        String nome2 = arquivo2 == null ? null : arquivo2.getFilename();
        return comparaNomesDeArquivos(nome1, nome2);
    }
    

    Oh, and let's assume that the above methods are in a class called String .

    Finally, you can sort your getFilename() using method Ordenacao :

    Collections.sort(suaArrayList, Ordenacao::comparaArquivosPorNome);
    

    If you're only using List<Arquivo> instead of sort(List<T>, Comparator<? super T>) , use this:

    Collections.sort(suaArrayList, Ordenacao::comparaNomesDeArquivos);
    

    Test

    To test all this, let's assume that this is the class List<String> :

    public class Arquivo {
        private String nome;
    
        public Arquivo(String nome) {
            this.nome = nome;
        }
    
        public String getFilename() {
            return nome;
        }
    
        @Override
        public String toString() {
            return "arquivo {" + nome + "}";
        }
    }
    

    And let this be the class that runs our tests:

    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;
    import java.util.stream.Collectors;
    
    public class Teste {
        public static void main(String[] args) {
            // 1. Cria as listas.
            List<String> lista1 = Arrays.asList(
                "batata", "batata0", "batata000", "batata3", null, "azul 6", "azul 50", "azul 51", "batata", "azul 051", "azul 5", "laranja"
            );
            List<Arquivo> lista2 = lista1.stream().map(Arquivo::new).collect(Collectors.toList());
    
            // 2. Ordena as listas.
            Collections.sort(lista1, Ordenacao::comparaNomesDeArquivos);
            Collections.sort(lista2, Ordenacao::comparaArquivosPorNome);
    
            // 3. Mostra as listas ordenadas.
            System.out.println(lista1);
            System.out.println(lista2);
        }
    }
    

    Here is the output produced:

    [null, azul 5, azul 6, azul 50, azul 051, azul 51, batata, batata, batata0, batata000, batata3, laranja]                                                                                                      
    [arquivo {null}, arquivo {azul 5}, arquivo {azul 6}, arquivo {azul 50}, arquivo {azul 051}, arquivo {azul 51}, arquivo {batata}, arquivo {batata}, arquivo {batata0}, arquivo {batata000}, arquivo {batata3}, arquivo {laranja}] 
    

    See all that working on the tutorialspoint site.

    >     
    17.12.2016 / 17:23
    0

    Once I had to sort my list by date, and sqlite did not treat it as a date, which I did:

    @Override
        public int compareTo(Call another) {
    
            SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
            java.util.Date dateComparer, dateActual;
    
            try {
                dateActual = sdf.parse(this.getData());
                dateComparer = sdf.parse(another.getData());
    
                if (dateActual.before(dateComparer)) {
                    return Constants.SUCESS;
                }
                if (dateActual.after(dateComparer)) {
                    return Constants.ERROR;
                }
    
            } catch (ParseException e) {
                e.printStackTrace();
            }
    
            return 0;
        }
    

    Then I ordered my list on the call:

    Collections.sort(calls)
    

    So I guess you would just have to convert String to integer and compare.

        
    17.12.2016 / 15:56