A maioria das tarefas na minha escola para as aulas de programação iniciais exigiam que eu usasse matrizes. Agora trabalho em período integral e nunca usei uma matriz para nenhum projeto em que trabalhei. Mesmo nos projetos existentes, nunca vi o uso de matrizes em nenhum lugar. Na minha opinião, a Lista é mais fácil de usar e é um padrão. Por que os professores dizem aos alunos para usar matrizes em suas tarefas? É apenas para que os alunos entendam o básico?
Como a maioria das universidades ensina Java, essa pergunta é específica para Java.
java
programming-languages
programming-practices
Uivos Hagrid
fonte
fonte
Respostas:
Como matrizes ensinam conceitos como indexação e limites, dois conceitos fundamentalmente importantes na programação de computadores.
Listas não são um "padrão". Existe uma grande variedade de espaços problemáticos para os quais as matrizes são um ajuste perfeito.
fonte
Eles provavelmente queriam começar com a estrutura de dados que representa com mais precisão o funcionamento de um computador, para que você esteja familiarizado com os fundamentos antes de começarem a apresentar abstrações de nível superior, como Listas, que facilitam o trabalho. Caso contrário, você não teria como entender por que uma certa estrutura ou algoritmo é lento / rápido para algumas operações e outras não; se a memória do computador fosse realmente feita de listas vinculadas, o mundo seria um lugar muito diferente.
Pelo mesmo motivo, minha primeira aula de programação na faculdade foi em C, e o restante das aulas foi em C ++, Java e outras linguagens. Não é que C seja de alguma forma melhor ou mais fácil, é que C (e Array) não esconde nada de você.
fonte
As respostas acima são ótimas, mas tenho outra em mente. O
main()
método de Java significa que os alunos encontram matrizes básicas muito cedo, geralmente logo no primeiro dia de aula. Por quê?É a primeira coisa com a qual você terá que lidar para escrever Hello World e além. (Vi alguns cursos usando IDEs de ensino como o BlueJ no início, o que permite apontar e clicar para executar métodos arbitrários, mas vamos deixar de lado ...) Embora possa valer a pena passar algumas das essas palavras-chave por um tempo, mais cedo ou mais tarde a maioria dos professores desejará explicá-las. De fato, uma pergunta clássica de teste no nível iniciante é pedir aos alunos que forneçam o significado de cada palavra-chave em um programa básico do Hello World. E o que encontramos como parte de nossa principal assinatura de método? Uma matriz (a razão para isso é, em parte, histórica. ArrayList não existia no Java 1.0). Matrizes fazem parte desse conjunto básico de conhecimento. Lista não é.
Dito isso, não é incomum que as classes introduzam ArrayList um pouco mais tarde no curso, especialmente depois que os objetos e seu uso são cobertos. Até o currículo de AP Computer Science para Java inclui ArrayList (eu sei que costumava, e o Google parece indicar que ainda o faz), embora ignore o fato de que ArrayList implementa List e o restante do Framework de coleções.
Finalmente, é minha experiência que programas universitários de CS usam Java como um meio de explorar conceitos de programação e CS, em vez de ensinar aos alunos como se tornarem bons desenvolvedores de Java. Alguns programas podem se concentrar mais na criação de desenvolvedores profissionais, enquanto outros se concentram mais na teoria, mas em ambos os casos, há muito a aprender sobre como usar Java no trabalho profissional real que não será ensinado na maioria dos currículos das faculdades. Isso varia de padrões e técnicas de design como os do Effective Java a estruturas como Spring, Hibernate ou JUnit, ou coisas ainda mais comuns, como JSP ou JDBC. Com essa filosofia em mente, enfatizar matrizes sobre o ArrayList mais comumente usado faz um pouco mais de sentido.
fonte
Um motivo pelo qual as aulas de programação do primeiro ano usam matrizes é o legado: foi assim que os professores a aprenderam antes de começarmos a usar bibliotecas padrão com listas dinâmicas inseridas. O uso dos tipos de dados primitivos também é mais aplicável: matrizes existem em praticamente qualquer computador idioma sob o sol (e pode ser implementado em várias instruções de montagem). Quando aprendi a programar, implementar uma lista vinculada era uma das tarefas.
É muito mais fácil começar com os primeiros princípios e depois dizer "Essa é a estrutura básica. Essa linguagem (ou suas bibliotecas) fornece essa estrutura de dados de alto nível que faz tudo isso, mas fornece x, ye z". é dizer "Então essas são as estruturas de dados de alto nível, agora aqui está o que está por trás". Aprender a raciocinar sobre o uso de um LinkedList versus um ArrayList (ou um HashSet versus um TreeSet) geralmente é um curso de Algoritmos do segundo ou terceiro ano. Listas e Mapas têm as mesmas interfaces e fornecem os mesmos resultados, mas podem ter comportamentos dramaticamente diferentes em um aplicativo de qualquer tamanho. E depois que você sai da Programação 101, não há garantia de que a Programação 102 estará usando o mesmo idioma. Se você começar do conceito de uma matriz, poderá dizer "
Outro motivo para preferir "matriz" a "Lista" em um curso introdutório é que as matrizes são fundamentalmente fáceis de entender: uma matriz de 20
bytes
ocupa 20 bytes (mais algumas para indicar o final da matriz ou o comprimento, dependendo da implementação )Uma "Lista" é uma chaleira de peixe completamente diferente e pode ser implementada de várias maneiras diferentes (ArrayList, LinkedList e provavelmente algumas que eu esqueci), com características de desempenho fundamentalmente diferentes. Sem entender as entranhas do que as diferentes classes Lista está fazendo, você não pode ter uma discussão significativa sobre quando você deve usar
List foo = new ArrayList()
vs.List foo = new LinkedList()
. Se você tentar fazer com que o aluno use uma implementação de lista, alguém perguntará por que você está usando ArrayList em vez de uma das outras implementações. E "ArrayList" inclui a palavra "Array" e é apoiada por um, portanto, não é realmente um grande salto lógico de "array" para "ArrayList".Ao contrário da crença popular, há situações em que faz sentido usar matrizes sobre listas, principalmente quando você está lidando com uma lista de tamanho estático. Aqui estão alguns:
foo[n]
desreferencia e faz alguma aritmética de ponteiro nos bastidores, enquantofoo.get(n)
precisa desreferenciar, fazer uma invocação de método, fazer uma segunda desreferência e, em seguida, talvez fazer aritmética de ponteiro (se você estiver usando um ArrayList; o LinkedLists potencialmente precisará iterar sobre todos os elementos da lista).int[] foo = new int[]{1, 2, 3, 4, 5}
vs. as sugestões em Outra pergunta do StackOverflowfonte
perm
é umint[256]
que possui uma permutação, pode-se invertê-lo facilmente com uma matriz:int[] inv = new int[256]; for (int i=0; i<256; i++) inv[perm[i]]=i;
não acho que qualquer coisa que alguém possa escrever com umArrayList<>
seria tão limpo.ArrayList
poderia facilmente receber um construtor que cria uma lista inicializada por padrão de um determinado tamanho.get
eset
não for informado.get
eset
pode ser in-alinhado, algo comomyList.set(23,myList.get(23)+1)
será longe de ser tão eficiente quantomyArray[23]+=1
. Além disso, mesmo para tipos que não precisariam de boxe, ficaria muito surpreso se algum JITter pudesse equivaler afor (i=0; i<1000; i++) myList2.set(i+2000,myList2.get(i+3000));
algo cujo desempenho esteja próximo.System.arrayCopy(myArray1,3000,myArray2,2000,1000);
Não há razão para o tipo de matriz dinâmica de uma estrutura não oferecer uma operação rápida de intervalo de cópias, mas Java não.Java permite que variáveis de qualquer tipo sejam armazenadas em matrizes. Por outro lado,
ArrayList
permite apenas o armazenamento de referências. Portanto, não é útil discutirArrayList
sem antes abordar como o boxe automático converterá primitivas em tipos de referência e como o unboxing às vezes converterá tipos de referência em primitivas:Se o código tivesse usado um
int[3]
e não umArrayList
, não haveria surpresas. Todos os três elementos seriam comparadosi
entre si.ArrayList
No entanto, usando todos os três elementos da lista sempre serão iguaisi
e o primeiro e o terceiro sempre são iguais, os dois primeiros só se igualam quandoi
1, 10 ou 100, mas (na maioria das implementações) não quandoi
for 1000 ou 10000.fonte
Integer
classe aninhou a classe chamadaIntegerCache
que contémInteger
objetos pré-inicializados para um intervalo de valores que normalmente se estende de -128 a 127; encaixar um valor fora desse intervalo exigirá a criação de um novo objeto, mas encaixar um valor dentro do intervalo em cache simplesmente retornará uma referência a um dos objetos pré-inicializados armazenados emIntegerCache.cache
. Qualquer bom programador Java precisa estar ciente de que asInteger
variáveis de dois tipos que encapsulam o mesmo valor podem ou não ser iguais, mas a introdução dessa idéia muito cedo pode fazer os alunos fugir aterrorizados.==
. Dada a possibilidade de que o auto-unboxing possa ser lançado, eu estaria inclinado a desautorizá-lo completamente, mas seu comportamento==
é especialmente horrível. O==
operador também se comporta mal em casos como16777217==16777216f
[relatórios verdadeiros], e as conversões implícitas paralong v=Math.Round(123456789), w=Math.Round(123456789012345)
tendem a ser inesperado [você pode adivinhar o que essas expressões irá produzir?]IntegerCache
, certamente há momentos em que ele pode ajudar no desempenho, mas frequentemente pode fazer com que um código que esteja simplesmente errado esteja meio que funcionando. De certa forma, eu gostaria que houvesse um modo em que o boxe retornasse objetos de forma quase aleatória a partir de dois caches inteiros e substituísse itens de cache quase aleatoriamente por novos, para que o código baseado no comportamento de boxe dos valores -128..127 fosse improvável que tenha sucesso por muito tempo.Eu acho que faz sentido ensinar como usar matrizes primeiro devido ao fato de que
ArrayList
usa uma matriz internamente. AArrayList
classe tem uma variável de membro chamadaelementData
which is aObject
array.No
ArrayList
código-fonte JDK :Quando você adiciona, atualiza, recupera ou remove elementos de um
ArrayList
objeto, ele usa essa matriz interna para executar essas operações. Como o usuário Ixrec já apontou -ArrayList
é apenas uma abstração de nível superior que normalmente é mais fácil de trabalhar.fonte
Java
- Ele estava perguntando por que ensinar matrizes quando normalmente você pode usarArrayList
. Java não tem ponteiros. Certo ou errado, tenho a opinião de que C / C ++ é uma linguagem melhor para começar os alunos do que Java. Muitos tópicos de programação podem ser melhor compreendidos com o conhecimento de C / C ++.Supondo que essa lista seja realmente mais fácil de trabalhar, como você diz - isso realmente não importa. Aprender é mais "básico ao complexo" do que "fácil ao difícil". Se os fundamentos não fossem importantes, a ciência da computação não seria um campo acadêmico. Você pode aprender como clicar em aplicativos juntos usando estruturas / bibliotecas existentes em tutoriais online. (Claro, alguém tem que escrever essas bibliotecas ... e alguém tem que implementar
ArrayList
em primeiro lugar ....)fonte
ArrayList
pode ser melhor tratado usando uma matriz separada e a contagem de "liveItems", exceto que não há uma maneira conveniente de trabalhar com a matriz e contar juntos, exceto agregando-os.É porque a coisa mais crucial na educação acadêmica é ensiná-lo a usar a terminologia correta para descrever o que você faz.
Lista é outra coisa que matriz. e Você não pode usar
java.util.List
em Java porque é uma interface. Você costuma usar o fato dejava.util.ArrayList
ser uma implementação de Lista não uma lista, mas um invólucro de objeto em torno da matriz dinâmica. Então você diz que usa uma 'Lista', mas usa uma matriz.É muito razoável pular esse caos terminológico e simplesmente usar matrizes para aprender aos alunos o que é matriz. Se você usa matrizes em Java, pelo menos usa matrizes.
Honestamente, também é o argumento de por que ensinar programação em Java não é uma boa idéia. É difícil aprender os conceitos básicos de programação corretamente.
fonte
Você literalmente nunca viu ou usou matrizes? Nós os usamos o tempo todo, além de listas. Geralmente não usamos Java, mas usamos muitas outras linguagens que desenham semelhanças óbvias.
Entre matrizes e Listas, um é mais leve e, além disso, mais direto ao ponto, enquanto o outro tem mais funcionalidade. Como regra geral na programação, quando existem dois tipos semelhantes que são basicamente divididos nessas linhas, você deve optar pelo mais leve, a menos que realmente precise do mais sofisticado. Além de reduzir a sobrecarga, isso realmente ajuda a controlar a quantidade de confusão e o estado no programa e, principalmente, seu código . Se algo der errado durante o teste, você terá menos lugares para procurar; e mais importante, no caso de matrizes x listas, as pessoas têm uma idéia melhor do escopo limitado do que você está realmente usando e tentando fazer com ele.
E sim, do ponto de vista acadêmico, há o motivo adicional de ensinar aos alunos o básico. No entanto, isso vai um pouco mais fundo. Matrizes e listas são um bom exemplo de tipos mais volumosos, muitas vezes apenas sendo criados sobre, e frequentemente envolvendo, instâncias subjacentes dos tipos mais leves. Mesmo quando as listas não têm matrizes subjacentes, elas se comportam externamente como elas. Uma parte de ensinar a alguém o que é uma lista seria ensinar a eles o que é uma matriz.
Eu pude ver isso talvez ficando fora de controle em uma linguagem como C ++, onde as matrizes basicamente não poderiam ser mais reduzidas do que são, mas em linguagens de nível superior, elas são quase listas por si mesmas. Se eles atendem perfeitamente às suas necessidades em uma determinada situação, por que você precisaria usar outra coisa?
fonte
T[]
estará pronto, imediatamente, para aceitar itens em qualquer ordem, enquanto umArrayList<T>
exige que os itens sejam adicionados, em ordem, antes que possam ser modificados. AT[]
pode copiar um intervalo arbitrário de itens para um tamanho similar de outroT[]
relativamente rápido, enquantoArrayList<T>
exigiria a leitura de itens individualmente de uma lista e o armazenamento na outra - muito mais lento e menos conveniente.