Bom dia,
A pergunta é mais generalista do que a descrita no título, pois pode ser feita pra vários dos métodos da classe Collections.
Alguém sabe o motivo para que alguns dos métodos da classe Collections não sejam métodos das interfaces List, Set, etc? Pois na minha visão, a versão alternativa seria mais OO, ou estou enganado?
Abs.
IMO, pra ser DRY.
Como List é uma interface, ela não possue implementação. Neste caso, se tivessemos sort na interface, cada implementação de List deveria repetir o mesmo código. Neste caso é melhor criar um método estático comum pra todo mundo que implemente List. Além disso, pra poder ser ordenada, uma lista deve conter objetos que implementem Comparable.
[quote=tveronezi]IMO, pra ser DRY.
Como List é uma interface, ela não possue implementação. Neste caso, se tivessemos sort na interface, cada implementação de List deveria repetir o mesmo código. Neste caso é melhor criar um método estático comum pra todo mundo que implemente List.
[/quote]
Mas a AbstractList não está lá pra resolver esse problema?
[quote=tveronezi]IMO, pra ser DRY.
Além disso, pra poder ser ordenada, uma lista deve conter objetos que implementem Comparable.
[/quote]
Talvez, isso sirva pra justificar o sort(), mas não outros métodos, como o shuffle(), por exemplo.
Acho que a duplicidade de implementação não é o principal motivo, porque (1) como foi observado, seria simples colocar a implementação em uma classe mãe comum, como a AbstractList; e (2) A implementação do sort não precisa ser necessariamente a mesma para diferentes listas, pois cada uma poderia fazer da maneira mais otimizada para aquela estrutura em particular.
O que eu considero que motivou essa decisão foi a ideia de que a estrutura de dados e os algoritmos que fazem determinadas operações (sort, shuffle, search, troca-troca, etc) conceitualmente não fazem parte do mesmo objeto. Poderiam funcionar independente um do outro, trocando-se à vontade tanto a estrutura como o algoritmo.
Enfim… talvez nem todo mundo concorde com essa ideia (será que existe uma resposta absoluta nesse caso :?: ), mas acho que era o que pensavam os designers do frameworks de coleções. Inclusive pode ser influência do C++ , onde os algoritmos não são membros das coleções (containers) e sim funções globais.
[quote=gomesrod]Acho que a duplicidade de implementação não é o principal motivo, porque (1) como foi observado, seria simples colocar a implementação em uma classe mãe comum, como a AbstractList; e (2) A implementação do sort não precisa ser necessariamente a mesma para diferentes listas, pois cada uma poderia fazer da maneira mais otimizada para aquela estrutura em particular.
O que eu considero que motivou essa decisão foi a ideia de que a estrutura de dados e os algoritmos que fazem determinadas operações (sort, shuffle, search, troca-troca, etc) conceitualmente não fazem parte do mesmo objeto. Poderiam funcionar independente um do outro, trocando-se à vontade tanto a estrutura como o algoritmo.
Enfim… talvez nem todo mundo concorde com essa ideia (será que existe uma resposta absoluta nesse caso :?: ), mas acho que era o que pensavam os designers do frameworks de coleções. Inclusive pode ser influência do C++ , onde os algoritmos não são membros das coleções (containers) e sim funções globais.[/quote]
Pode ser isso mesmo… estou achando que grande parte é questão de gosto.
A questão, é que list.sort() dá impressão de ser algo mais OO (a ordenação poderia ser vista como um comportamento) e tem a vantagem de não precisar passar parâmetro. Por outro lado, como você bem disse, algumas pessoas podem achar que a list está fazendo mais do que deveria, deixando-a com baixa coesão.
Engraçado é ver que Python (se não me engano) é o contrário do Java: a ordenação é feita com list.sort() mas, para pegar o tamanho, é preciso fazer len(list)…
Outro ponto que acho interessante:
len(list) em Python retorna o tamanho da lista.
já Collections.sort(list) de Java não retora uma list, mas modifica a que é passada como parâmetro. Só eu acho esse comportamento um pouco estranho? Parece que algo como:
List<QualquerCoisa> qc = Collections.getSorted(list);
sem modificar a list original seria menos pior…
Aliás, da maneira como está, é como se estivéssemos passando um ponteiro de retorno em C, que é feio pra caramba. Se não me engano, o Clean Code desencoraja a alteração de estado de objetos passados por parâmetro.
quantas pessoas aprendendo Java já não tentaram fazer isso?
System.out.println(Collections.sort(list));
Se tivesse que escolher só um dos dois para ser parte intrínseca do objeto list eu ficaria do lado do Java e escolheria o size 
IMO, acho que nenhuma das formas estaria correta.
Organizar não é uma função de uma lista, mas de um Organizador.
Pensando dessa forma, acho que, deveria ter uma classe do tipo Sorter e esta sim teria a inteligência para realizar a organização da classe.
Poderia ter uma fábrica (Factory ou Builder) onde forneceria a classe-base e retornaria uma implementação específica e formas de fornecer implementações para casos não abordados (onde o desenvolvedor criaria pontos que mapeariam a lógica adequada, como é feito quando fornece-se um Comparator).