Professional Documents
Culture Documents
1. ARQUITETURA E FERRAMENTAS
1.1. Como compilar e executar um programa Java?
O conceito de um algoritmo foi formalizado em 1936 pela Máquina de Turing de O
processo de compilação de um programa Java é feito de acordo com os seguintes passos: o
código fonte (extensão .java) é compilado e armazenado em um arquivo de extensão .class.
De cara, percebe-se a impossibilidade de utilizar-se de DOS como sistema operacional para a
elaboração de aplicativos Java, uma vez que o mesmo tem um suporte limitado a nomes de
arquivos. Mas essa limitação quanto ao nome dos arquivos é somente a razão aparente da não-
portabilidade de Java para DOS. A grande razão reside no fato de que Java foi projetada para
sistemas de 32 bits, e só foram escritas Máquinas Virtuais Java para ambientes de 32 bits.
A portabilidade de Java depende fortemente da existência de JVMs que rodem em
diversas plataformas. Um programa Java rodará em um computador se existir uma JVM que
nele rode. Ao contrário de programas Java, as JVMs devem ser programas feitos e compilados
para máquinas específicas, de forma que serão as JVMs as responsáveis pela tradução de
bytecodes Java para as linguagens nativas das máquinas.
O conjunto de instruções da Máquina Virtual Java é otimizado para ser pequeno e
compacto, tendo sido elaborado para ser uma espécie de processador RISC(siginificado)
virtual: a rapidez da interpretação às vezes é sacrificada para garantir esse reduzido conjunto
de instruções.
O compilador mais utilizado para a transformação de arquivos-fonte java (.java) em
arquivos de bytecodes é o javac da Sun (há diversos outros compiladores no mercado, mas o
javac foi o primeiro e é o mais popular ainda hoje).
.
Figura 2 Funcionamento da JVM(Java Virtual Machine)
Com isso um programa Java é um conjunto de instruções para a JVM, dessa forma o
mesmo é independente de plataforma, pois basta que haja uma implementação de máquina
virtual para a plataforma a ser utilizada.
Observação: Esse foi o modelo inicial para execução de programas Java, a fim de
possibilitar independência de plataforma, sendo que atualmente o processo de interpretação
foi substituído por outra compilação, sendo que, não mais para bytecodes e sim para código
executável dependente de plataforma. Dessa forma a perda de performance com a
interpretação foi eliminada e o programa em bytecodes continua independente de plataforma,
pois a JVM de cada plataforma será responsável pela compilação em executável.
Site http://www.javasoft.com/products/hotspot/
(s)
Feito isso, irá aparecer a licença do Java. Aperte "enter" para rolar a página ou "q"
para terminar. Após isso, digite "yes" para concordar com os termos da licença, e sendo
assim, irá começar a descompactar os arquivos. (será criado o diretório "j2sdk").
Pronto, o Java está instalado, porém agora falta configurá-lo.
Edite o arquivo /etc/profile (como root, claro) e adicione as seguintes linhas:
JAVA_HOME:/usr/local/j2sdk<versão>
CLASSPATH=.:$CLASSPATH
No "JAVA_HOME", coloque o diretório onde foi criado o j2sdk. (no meu caso foi
criado em /home/juniox/j2sdk).
Feito isso, procure pela linha PATH e adicione logo abaixo:
PATH=$JAVA_HOME/bin:$PATH
No artigo que fala sobre o J2DK, era para colocar a linha
"PATH=$JAVA_HOME/bin:$PATH", mas uma dúvida.
Digamos que eu tenha colocado o Java no /root ou na raíz, como que
ficaria?
No PATH não vai mudar nada, pois nele você está indicando o
valor da variável $JAVA_HOME:
PATH=$JAVA_HOME/bin:$PATH
JAVA_HOME:/root/j2sdk<versão>
As linhas do /etc/profile. Eu inseri o que segue:
#
# /etc/profile
.
.
.
# final do /etc/profile
export PATH=/usr/local/j2sdk1.4.2:$PATH
#<EOF>
1.3. Instalando o Java na sua máquina
Técnico em Informática – Lógica de Programação e Estrutura de Dados 4
O seu sistema deve estar pronto para compilar programas em Java. Para fazer um teste, abra
um prompt do MSDOS, e digite:
javac
Tudo estará funcionando caso apareça uma grande mensagem explicando como utilizar o
javac.
2. O Básico
2.1. Convenção da linguagem
Na linguagem Java é utilizada a seguinte convenção para formação de
identificadores:
Um bloco é definido por ({}) e contém um grupo de outros blocos. Quando um novo
bloco é criado um novo escopo local é aberto e permite a definição de variáveis locais. As
variáveis definidas dentro de um bloco só podem ser vistas internamente a este, e são
terminadas ou extintas no final da execução deste(}).
2.5. Comentários
Técnico em Informática – Lógica de Programação e Estrutura de Dados 6
Literais reservados
De acordo com a Java Language Specification, null, true e false são tecnicamente chamados de valores
literais, e não keywords. Se você tentar criar algum identificador com estes valores, você também terá um erro de
compilação.
b. Crie o arquivo ao lado em um diretório qualquer (“folder” para usuários mac) e salve
com o nome: HelloInternet.Java
d. Seu diretório deve ter recebido um novo arquivo após essa compilação:
HelloInternet.class
e. Chame o interpretador Java para este arquivo (omita a extensão .class de arquivo):
Java HelloInternet
System.out.println("Hello!");
Resultado:
Hello!
2.7.1.2. Explicação passo a passo do programa exemplo:
Técnico em Informática – Lógica de Programação e Estrutura de Dados 9
Comentários em Java seguem a mesma sintaxe de C++, “//” inicia uma linha de
comentário, todo o restante da linha é ignorado. Existe também um outro tipo de comentário
formado por /* Insira aqui o texto a ser ignorado */ , este tipo de comentário pode ser
intercalado em uma linha de código. Comentários são tratados como espaços em branco. E
por último o comentário para documentação /** até o final */ deve vir antes da declaração da
classe.
class é a palavra reservada que marca o inicio da declaração de uma classe. Public é um
especificador, por enquanto guarde public class como o início da declaração de uma classe.
Toda classes serão declaradas assim até o tópico POO (Programação Orientada a Objetos).
HelloInternet
É o nome dado a esta classe. O “abre chaves” marca o início das declarações da classe
que são os atributos e métodos. Esta classe só possui uma declaração, a do método main, note
que um método, ao contrário de C++, só pode ser declarado {internamente} a classe a qual
pertence, evitando as confusões sobre “escopo”. Desta forma, todo pedaço de código em Java
deve pertencer ao abre chaves, fecha chaves da definição de uma classe.
public
É um qualificador do método que indica que este é acessível externamente a esta classe
(para outras classes que eventualmente seriam criadas), não se preocupe com ele agora,
apenas declare todos os métodos como public. Voltaremos a este assunto em outro capitulo.
static
É outro qualificador ou “specifier”, que indica que o método deve ser compartilhado por
todos os objetos que são criados a partir desta classe. Os métodos static podem ser invocados,
mesmo quando não foi criado nenhum objeto para a classe, para tal deve-se seguir a sintaxe:
<NomeClasse>.<NomemetodoStatic>(argumentos);. Retornaremos a esta explicação mais
tarde, por hora você precisa saber que particularmente o método main precisa ter essa
qualificação porque ele é chamado sem que se crie nenhum objeto de sua classe (a classe
HelloInternet).
2.7.1.3. Curiosidade:
A linguagem de programação Eiffel adota uma técnica diferente para resolver este
problema: todo programa começa com a criação de um objeto (e não mais a chamada
automática de main), este objeto é chamado ROOT, ele pode conter atributos que são
inicializados e um método de inicialização, construtor do objeto, que é o início do código do
programa.
void
main
Este é um nome particular de método que indica para o compilador o início do programa,
é dentro deste método e através das iterações entre os atributos, variáveis e argumentos
visíveis nele que o programa se desenvolve.
(String args[])
{ ... }
“Abre chaves” e “fecha chaves”. Para quem não conhece C ou C++, eles podem ser
entendidos como algo semelhante ao BEGIN END de Pascal ou Modula-3, ou seja: delimitam
um bloco de código. Os programadores Pascal notarão que variáveis locais dos métodos
podem ser declaradas em qualquer local entre as chaves. Mas por motivos de clareza do
código declararemos todas no início do abre chaves.
2.8. Identificadores
Os identificadores em Java devem seguir as seguintes regras:
Uma constante é definida com a palavra reservada final e o seu conteúdo uma vez
atribuído não poderá mais ser alterado.
A declaração de variáveis e constantes em Java é feita colocando o identificador do tipo
seguido do identificador da variável.
long a = 1;
int b = 2;
a = b; // Conversão válida
//b = a; // Conversão
inválida
b = (int) a; // Conversão
válida
Tipo Faixa
boolean true ou false
2.15.1.1. Conversão
Char
Short
Byte
2.16. STRING
String é uma classe que manipula cadeias de caracteres
A classe String possui métodos para essas manipulações
Trabalha com Pool de Strings para economizar memória
Técnico em Informática – Lógica de Programação e Estrutura de Dados 15
Exemplo:
}
System.out.println( “Tamanho da String: “ + str.length() );
System.out.println( “SubString: “ + str.substring(0, 10) );
System.out.println( “Caracter na posição 5: “ + str.charAt(5) );
2.17.1.1. Atribuição
2.17.1.2.
Técnico em Informática – Lógica de Programação e Estrutura de Dados 16
2.17.1.3. Aritméticos
Exemplo Aritmético:
public class Aritmeticos {
public static void main ( Strings args[] ) {
short x = 6;
int y = 4;
float a = 12.5f;
float b = 7f;
System.out.println ( “x é “ + x + “, y é “ + y );
System.out.println ( “x + y = “ + (x + y) );
System.out.println ( “x - y = “ + (x - y) );
System.out.println ( “x / y = “ + (x / y) );
System.out.println ( “x % y = “ + ( x % y ) );
System.out.println ( “a é “ + a + “, b é “ + b );
System.out.println ( “ a / b = “ + ( a / b ) );
}
}
x é 6, y é 4
x + y = 10
x-y=2
x/y=1
x%y=2
a é 12.5, b é 7
a / b = 1.78571
Técnico em Informática – Lógica de Programação e Estrutura de Dados 17
As duas expressões dão resultados diferentes, pois existe uma diferença entre prefixo e
sufixo. Quando se usa os operadores ( x++ ou x-- ), y recebe o valor de x antes de x ser
incrementado, e usando o prefixo ( ++x ou –x ) acontece o contrario, y recebe o valor
incrementado de x.
2.18. Operadores
2.18.1.1. Relacionais
Operador Descrição
== Igual
!= Diferente
< Menor
> Maior
<= Menor ou igual
>= Maior ou igual
2.18.1.2. Binários
Operador Descrição
>> shift binário para direita
<< shift binário para esquerda
>>> shift binário para direita (unsigned)
& AND binário
| OR binário
^ XOR binário
~ Inversão de Bits
2.18.1.3. Lógicos
2.18.1.4. Condicional
Descrição Operadores
operadores do sufixo [ ] . () Chamada de função
operadores unários !, ~, +, -, ++, --
Criação (Type-cast), new
multiplicativos *, /, %
aditivos +, -
SHIFT <<, >>, >>>
relacional <, >, <=, >= instanceof
igualdade ==, !=
AND binário &
XOR binário ^
OR binário |
AND lógico &&
OR lógico ||
Condicional ?:
Atribuição +=, -=, *=, /=, %=, &=, ^=, |=, <=, <=, >>, >=, >>, =
Incremento e Decremento: ++ e --
int a = 0;
int b = a++; // incrementado depois de atribuir
int c = ++a; // incrementado antes de atribuir
b = a--; // decrementado depois de atribuir
c = --a; // decrementado antes de atribuir
Inversão de Bits: ~
Complementar booleano: !
double d = 1.99;
int i = (int) d; // converte de double p/ int (perda de
//precisão)
Multiplicação e Divisão: * e /
Concatenação:
Número: 192
Binário: |00000000|00000000|00000000|11000000|
Right Shift de 1 bit: |00000000|00000000|00000000|01100000|
Right Shift de 7 bits: |00000000|00000000|00000000|00000001|
Resultado
int i = 192 >> 1
int i = 192 >> 7
Número: -192
Binário: |11111111|11111111|11111111|01000000|
Right Shift de 1 bit: |11111111|11111111|11111111|10100000|
Right Shift de 7 bits: |11111111|11111111|11111111|11111110|
Resultado
int i = -192 >> 1
int i = -192 >> 7
Número: 192
Binário: |00000000|00000000|00000000|11000000|
Left Shift de 1 bit: |00000000|00000000|00000001|10000000|
Left Shift de 7 bits: |00000000|00000000|01100000|00000000|
Resultado
int i = 192 << 1
int i = 192 << 7
Número: -192
Binário: |11111111|11111111|11111111|01000000|
Left Shift de 1 bit: |11111111|11111111|11111110|10000000|
Left Shift de 7 bits: |11111111|11111111|10100000|00000000|
Resultado
int i = -192 << 1
int i = -192 << 7
Número: 192
Binário: |00000000|00000000|00000000|11000000|
Right Shift de 1 bit: |00000000|00000000|00000000|01100000|
Right Shift de 7 bits: |00000000|00000000|00000000|00000001|
Resultado
int i = 192 >>> 1
int i = 192 >>> 7
Número: -192
Binário: |11111111|11111111|11111111|01000000|
Right Shift de 1 bit: |01111111|11111111|11111111|10100000|
Right Shift de 7 bits: |00000001|11111111|11111111|11111110|
Resultado
int i = -192 >>> 1
int i = -192 >>> 7
Operador instanceof
Comparação de Igualdade: == e !=
Numéricos Inteiros:
Operando A: 1
Operando B: 3
Binário de A: 00000001
Binário de B: 00000011
A & B: 00000001 = 1
A ^ B: 00000010 = 2
A | B: 00000011 = 3
Booleanos:
int x = 10;
int y = (x > 10) ? x : x+1;
é semelhante ao código abaixo:
int x = 10;
int y;
if( x > 10 ) {
y = x;
} else {
y = x + 1;
}
System.out.print(String);
System.out.println(String); //Salta Linha
Observação: Tipos primitivos/ “objetos” podem ser concatenados com o sinal "+".
Vejamos o seguinte começo de código, que nos ajudará na inserção dos dados, sem
discutirmos cada classe e método, pois, veremos em Estrutura de Dados.
import java.io.*;
import java.util.*;
Na instrução:
try {
name = dataIn.readLine();
}
catch (IOException e) {
System.out.println("Error!");
}
Na instrução:
Definimos uma variável, denominada input, que será criada a partir da classe
Scanner e direcionada para a entrada padrão.
4. Estruturas de Controle
4.1. Estrutura de Seleção ou Condicional
4.1.1Comando if – else
Comando de seleção, o qual permite analisar uma expressão lógica e direcionar a
execução do programa. Caso a expressão lógica seja verdadeira (true) a sequência do if será
executado e caso a expressão lógica seja falsa (false), e exista a cláusula else, a sequência do
else será executada.
Uma alternativa para o uso do if e else é um operador ternário condicional. Este operador
ternário (?: ) , é chamado assim porque tem três termos como parâmetro.
Exemplo:
if ( expressão_lógica )
Sequência_1;
else
Sequência_2;
Técnico em Informática – Lógica de Programação e Estrutura de Dados 25
if ( expressão_lógica )
Sequência_1;
else if ( expressão_lógica )
Sequência_2;
else if ( expressão_lógica )
Sequência_3;
else if ( expressão_lógica )
Sequência_4;
else
Sequência_5;
import util.Scanner;
if ( bissexto ) {
data = true;
}
}
}
}
}
}
System.out.print(dia + "/" + mes + "/" + ano + " : ");
if ( data )
System.out.println("Data Válida");
else
System.out.println("Data Inválida");
}
}
Cláusula if( )
}
}
}
3. Comando while
Executa a sequência do comando enquanto a expressão lógica for verdadeira. Sendo que,
antes de cada execução a expressão lógica é analisada.
while ( expressão_lógica )
Sequência;
int count=0;
while( count < array1.length && array1[count]!=0){
array2[count]=(float) array1[count++];
}
Cláusula While( )
int fatorial;
4. Comando do while
Executa a seqüência do comando enquanto a expressão lógica for verdadeira. Sendo que,
após a execução da sequência a expressão lógica é analisada.
do
Sequência;
while ( expressão_lógica );
Cláusula do while( )
int fatorial;
Scanner input = new Scanner(System.in);
System.out.println("Calculo do fatorial (flag = 0)");
do {
System.out.print("Número : ");
numero = input.nextInt();
fatorial = 1;
while (numero > 1) {
fatorial *= numero;
numero--;
}
System.out.println("Fatorial : " + fatorial);
} while (numero != 0);
}
}
5. Comando for
Executa a sequência do comando enquanto a expressão lógica for verdadeira. Sendo que
permite inicializar variável, na entrada do comando e incrementar variável a cada repetição.
Você também pode incluir um comando simples, sendo assim não há necessidade da
utilização de chaves. Exemplo:
Cláusula For( )
import java.util.Scanner;
System.out.print("Tabuada de (+ x) : ");
char tabuada = input.next();
switch (variável) {
case valor1 : sequência_1;
case valor2 : sequência2;
...
case valorN : sequênciaN;
[ default : sequênciaDefault; ]
}
switch( numero ) {
case 1 :
System.out.println( "UM" );
break;
case 2 :
System.out.println( "DOIS" );
break;
case 3 :
System.out.println( "TRES" );
break;
default :
System.out.println( "NENHUM" );
break;
}
}
}
O switch recebe um argumento do tipo int ou char.
package Comando;
import java.util.Scanner;
case 12 :
if ( dia >= 1 && dia <= 31 )
data = true;
break;
/* fevereiro */
case 2 :
if ( dia >= 1 && dia <= 28 ) {
data = true;
} else {
/* 29 de fevereiro */
if ( dia == 29 ) {
/* Ano bissexto */
boolean bissexto = ( (ano % 4 == 0)&&
(ano % 100 != 0) ) ||
(ano % 400 == 0);
if ( bissexto ) {
data = true;
}
}
}
default : data = false;
}
4.4. Instruções
7. Comando break
Força a saída de um comando de repetição ou do comando switch
Cláusula break()
int j = 0, i = 0;
principal1: while( true ) {
for( i=0; i<1000; i++ ) {
if( j == 10 && i == 100 )
break principal1;
}j++;
}
8. Comando continue
Força o início da próxima iteração de um comando de repetição.
Cláusula continue()
Ignora a execução dos comandos seguintes do bloco, do laço rotulado, quando executado.
Programa(s)Demonstração ComandoBreakContinue.java
/**
* Demonstração do comando break e continue
*/
Técnico em Informática – Lógica de Programação e Estrutura de Dados 34
5.1. Fatorial
Na matemática, o fatorial de um número natural n, representado por n!, é o produto de
todos os inteiros positivos menores ou iguais a n. A notação n! foi introduzida por Christian
Kramp em 1808.
Por exemplo,
6. Estrutura de Dados
Como percebemos, se quisermos guardar dados de diferentes tipos teremos problemas,
pois, variáveis (de tipos primitivos) não suportam tipos diferentes de dados, não agora. Para
resolvermos teremos de agora para frente estudarmos Estrutura de Dados.
Além disto, temos as estruturas de dados dinâmicas que crescem e encolhem em tempo de
execução. Que são elas: Listas, Pilhas, Filas, Árvores.
6.1. Array
Array é uma coleção ordenada de primitivos, referências para objetos e outras arrays. Os
arrays em Java são homogêneos, ou seja, eles só podem conter dados do mesmo tipo. Os
arrays são objetos, e devem ser construídos antes de serem usados.
Lembrando que o nome array servirá para os conhecidos vetores e matrizes em outra
linguagem, aqui no Java trataremos com Array.
Passos para utilizar arrays:
- Declaração
Técnico em Informática – Lógica de Programação e Estrutura de Dados 37
- Criação
- Iniciação
Podemos percorrer os array de forma automática, usando o laço for( ). O índice dos arrays
vai de 0 (zero) até N-1 (onde N é o tamanho do array).
Exemplo:
public class PreencherComPesos {
public static void main( String[] args ) {
double[] pesos = new double[10];
//aqui sabemos o tamanho do array
for(int i=0; i<10; i++) {
peso[i] = 0;
}
}
}
public class PercorrendoArray {
public static void main( String[] args ) {
double[] precos = new double[100];
//aqui sabemos o tamanho do array
for(int i=0; i<100; i++) {
precos[i] = i * 2.99;
}
//aqui não importa o tamanho do array
for(int i=0; i<precos.length; i++) {
precos[i] = i * 2.99;
}
}
}
Os arrays não mudam de tamanho. Acessar um índice inexistente causa uma exceção:
ArrayIndexOutOfBoundsException.
import java.util.*;
Técnico em Informática – Lógica de Programação e Estrutura de Dados 38
Arrays possuem um atributo tamanho, que pode ser usado para determinar o tamanho, em
bytes, de um Array:
int arrayLength = intArray.length; // determinando o tamanho do Array
Lembre-se que isto é o número total de bytes ocupado pelo array e não o número de
elementos contidos nele. Como na maioria das linguagens de programação, em Java, não é
possivel alterar o tamanho de um Array depois da sua criação.
Sobre as Arrays temos algo que devemos estudar, array é uma matriz mesmo que seja de
uma coluna e uma linha (vetor), mais de uma linha e coluna(matriz), como chego nos
números inseridos na diagonal principal, na diagonal secundária, nos números abaixo da
diagonal principal, acima da diagonal secundária, os números impares do lado esquerdo entre
as diagonais, os números do lado direito entre a diagonal principal e a secundária? Todas estas
perguntas sanaremos no exemplo abaixo que será de uma matriz 5 X 5.
Obs: O encontro de uma linha com uma coluna forma uma célula
Técnico em Informática – Lógica de Programação e Estrutura de Dados 39
Achando as diagonais:
I. Diagonal Principal:
a. A Linha = Coluna
1 2 3 4 5
1 L1XC1
2 L2XC2
3 L3XC3
4 L4XC4
5 L5XC5
1 2 3 4 5
1 L1XC5
2 L2XC4
3 L3XC3
4 L4XC2
5 L5XC1
1 2 3 4 5
4 L4XC4 L4XC5
5 L5XC5
1 2 3 4 5
1 L1XC1
2 L2XC1 L2XC2
1 2 3 4 5
4 L4XC1 L4XC2
5 L5XC1
1 2 3 4 5
1 L1XC5
2 L2XC4 L2XC5
1 2 3 4 5
1 L1XC1 L1XC5
2 L2XC2 L2XC4
3 L3XC3
4 L4XC2 L4XC4
5 L5XC1 L5XC5
1 2 3 4 5
1 L1XC1 L1XC5
2 L2XC2 L2XC4
3 L3XC3
4 L4XC2 L4XC4
5 L5XC1 L5XC5
1 2 3 4 5
1 L1XC1 L1XC5
2 L2XC2 L2XC4
3 L3XC3
4 L4XC2 L4XC4
5 L5XC1 L5XC5
1 2 3 4 5
1 L1XC1 L1XC5
2 L2XC2 L2XC4
3 L3XC3
4 L4XC2 L4XC4
5 L5XC1 L5XC5
a. A se (L < C) e (L + C > 6)
1 2 3 4 5
1 L1XC1 L1XC5
2 L2XC2 L2XC4
3 L3XC3
4 L4XC2 L4XC4
5 L5XC1 L5XC5
7. Função e Procedimento
7.1. Procedimento
Static: é um modificador que indica que o método será alocado em memória sem que
haja necessidade de ser instanciado. Não necessita objeto; pode ser invocado com base no
nome da classe.
Os modificadores são elementos que caracterizam o método quanto à visibilidade
(esxcopo) e à qualidade. Os métodos, bem como as classes e as variáveis, podem possuir
mais de um modificador, não importando sua ordem. Alem do static, outros
modificadores muito utilizados são:
• public - pode ser invocado livremente e indica um método que é visível para
qualquer um que enxergue a classe;
• protected – pode ser utilizado apenas no mesmo pacote e em subclasses;
• private – pode ser invocado apenas na classe;
• final – não pode ser sobrescrito e equivale à declaração de constante.
7.2. Funções
import java.util.Scanner;
Parâmetros
Parâmetros são variáveis ou valores que podem ser transferidos do algoritmo principal
para um módulo que está sendo chamado. Eles funcionam como comunicadores entre os
módulos. Existem dois tipos de parâmetros: os formais e os reais.
Formais – são declarados nos módulos e tratados como as variáveis. Tem a função de
receber os valores passados do algoritmo que o chama. O algoritmo que chama a função ou o
procedimento informa os valores que substituirão esses parâmetros.
Exemplo:
Static void multiplicar (double a, double b) {
double res;
res = a + b;
System.out.println("Resultado é " + res);
}
Reais – são os valores passados pela rotina chamadora ao módulo (função ou
procedimento). Esses valores substituem os parâmetros formais.
Técnico em Informática – Lógica de Programação e Estrutura de Dados 47
Exemplo:
import java.util.Scanner;
public Classe2(){
Classe1 c = new Classe1();
System.out.println(c.nome + " , " + c.valor);
altera(c); //por referencia
System.out.println(c.nome + " , " + c.valor);
}
8. Busca e Ordenação
Quando o usuário insere os dados não se preocupa em como ordená-los ou como achará
algum valor dentro de suas variáveis (vetor, matrizes). Assim, é comum encontrarmos
elementos armazenados de maneira aleatória em nossos sistemas.
Para se ter um melhor desempenho em um programa a necessidade desta ordenação é de
grande importância.
8.1. Ordenação
Técnico em Informática – Lógica de Programação e Estrutura de Dados 49
Posição 1 2 3 4 5 6 7 8
Valores Iniciais 23 4 33 45 19 12 28 40
Iteração 1 4 23 33 45 19 12 28 40
Iteração 2 4 12 33 45 19 23 28 40
Iteração 3 4 12 19 45 33 23 28 40
Iteração 4 4 12 19 23 33 45 28 40
Iteração 5 4 12 19 23 28 45 33 40
Iteração 6 4 12 19 23 28 33 45 40
Iteração 7 4 12 19 23 28 33 40 45
Tabela 1 Exemplo de ordenação por seleção
Valores Inicias
Iteração 1
Iteração 2
Iteração 3
Iteração 4
Iteração 5
Iteração 6
Iteração 7
Posição
1 23 4 4 4 4 4 4 4
2 4 23 12 12 12 12 12 12
3 33 12 23 19 19 19 19 19
4 45 33 19 23 23 23 23 23
35 19 45 33 28 28 28 28 28
6 12 19 45 33 33 33 33 33
7 28 28 28 45 40 40 40 40
8 40 40 40 40 45 45 45 45
Tabela 2Exemplo de ordenação por trocas
8.3. Busca
Possuímos os dados e o que fazer com eles? Como recuperá-los com eficiência? A
responsabilidade é do programador.
Procurar por nomes e números em uma lista pequena é rápido, mas, quando esta lista
é enorme temos problema. Sistemas trabalham, frequentemente, com a busca de números,
códigos, nomes, siglas, etc. e precisam de uma resposta rápida para não comprometer seu
desempenho.
Os algoritmos de buscas são alguns dos mais utilizados no mundo da informática,
sendo aplicados em bancos dedados, internet e jogos, entre outros. Aqui serão apresentados
alguns exemplos de algoritmos de busca linear e busca binária.
A maneira mais fácil de fazer uma busca é comparar o elemento que se está
procurando com todos os elementos guardados, um a um, isto é, procurar o elemento
sequencialmente até que ele seja encontrado.
Técnico em Informática – Lógica de Programação e Estrutura de Dados 53
O algoritmo que realiza essa busca é uma estrutura de repetição que percorre toda a
sequência de elementos, realizando uma condicional que compara o elemento desejado
com os elementos existentes na sequência.
A classe Busca incorpora os dois métodos de busca referenciados pelo nome linear
que, como já dissemos, estão sobrecarregados, diferenciados pelos tipos dos dados passados
como parâmetros.
Além do método já citado, a classe String possui alguns métodos de comparação
direta entre dois string. O método equals (Object) é derivado da superclasse Object e pode ser
utilizado para comparar o conteúdo completo de dois objetos quaisquer, inclusive String. Esse
método é bastante utilizado,mas para nossos exemplos é mais conveniente utilizar o método
equalsIghoreCase (String), que faz a comparação apenas entre objetos do tipo String,
eliminando o problema de comparações entre minúsculas e maiúsculas.
public class Busca {
public static boolean linear(int x, int dados[]){
final int n = dados.length;
for(int i = 0; i < n; i++)
if (x == dados[i])
return true;
return false;
}
//com equalsIgnoreCase para eliminar problemasde
comparações entre minúsculas e maiúsculas
modificar ou ampliar essa classe para fazer pesquisa por meio do método de busca binária
para outro tipo qualquer ou para strings.
Exemplo completo com inserção de números no vetor, ordenação e pesquisa.
package tecest;
import java.util.Scanner; // importação da Classe Scanner
}
}
}
for (int i = 0; i < qte; i++){
System.out.println(numeros[i]);
}
System.out.println("Informe número a ser pesquisado: ");
numpesq = input.nextInt();
if (busca.binária(numpesq, numeros)==true)
System.out.println("O número pesquisado encontrado");
else
System.out.println("O número pesquisado não encontrado");
}
}
9.1. Listas
Uma lista é uma coleção de elementos do mesmo tipo dispostos linearmente que
podem ou não seguir determinada organização, por exemplo [E1, E2, E3, E4, E5,..., En], onde n
deve ser >= 0.
Exemplo de lista de pagamentos a serem efetuados em um mês:
Lista de pagamentos
Prestação do carro
Cartão de crédito
Conta de luz
Condomínio
TV a cabo
Supermercado
Quando criamos uma lista para ser utilizada como estrutura de dados, podemos usar
como contêiner para armazenamento dos dados um vetor ou uma matriz, então dizemos que
se trata de uma lista implementada por meio de arranjo (array). Por outro lado, também
podemos utilizar a alocação dinâmica, isto é, não criamos um contêiner para armazenar os
dados, mas precisamos referenciar os elementos seguinte e anterior de cada elemento, então
teremos uma lista encadeada.
Veja o exemplo acima de lista simples:
Lista de pagamentos ← [prestação do carro, cartão de credito, conta de luz, condomínio,
TV a cabo, supermercado]
Essa é uma lista que possui seis elementos do tipo literal, e os elementos estão
armazenados em um vetor.
exemplificar será utilizada a lista de pagamentos que devem ser efetuados no mês. Os
pagamentos estão dispostos em uma ordem linear:
Lista de pagamentos
Prestação do carro
Cartão de crédito
Conta de luz
Condomínio
TV a cabo
Supermercado
Olhando para a lista, pode-se perceber qual é o primeiro, qual o é o segundo e assim
por diante. Porém, quando desejamos implementar essa lista em uma estrutura de dados,
precisamos dizer qual será o próximo elemento. Para isso, cada elemento da lista é
representado por um nó, e cada nó deve conter os dados e um campo que indique qual é o
próximo elemento da lista – esse campo é chamado de referência (ou ponteiro como em outras
linguagens). Observe a seguinte lista com um campo para encadeamento.
Lista de pagamentos Referência para o próximo elemento
Prestação do carro 2
Cartão de crédito 3
Conta de luz 4
Condomínio 5
TV a cabo 6
Este é o último elemento do conjunto,
Supermercado
então não aponta para nenhum outro.
1
Prestação do carro 2 Cartão de crédito 3 Conta da luz
Vantagens:
• A inserção ou remoção de um elemento na lista não implica a mudança de
lugar de outros elementos;
• Não é necessário definir, no momento da criação da lista, o número máximo
de elementos que esta poderá ter. Ou seja, é possível alocar memória
"dinamicamente", apenas para o número de nós necessários.
Desvantagens:
• A manipulação torna-se mais "perigosa" uma vez que, se o encadeamento
(ligação) entre elementos da lista for mal feito, toda a lista pode ser perdida;
• Para aceder ao elemento na posição n da lista, deve-se percorrer os n - 1
anteriores.
IntNoSimples(int ValorNo){
valor = ValorNo;
prox = null;
}
Classe ListaSimples cria a estrutura de uma lista, cujos nós terão a estrutura definida
pela classe IntNoSimples. Neste exemplo, os nós são inseridos sempre no final da lista.
class ListaSimples {
IntNoSimples primeiro, ultimo;
int numero_nos;
ListaSimples() {
primeiro = ultimo = null;
numero_nos = 0;
}
class ExeListaSimplesCompleta {
IntNoSimples primeiro, ultimo;
int numero_nos;
ExeListaSimplesCompleta (){
primeiro = ultimo = null;
}
void insereNo_fim (IntNoSimples novoNo){
novoNo.prox = null;
if (primeiro == null)
primeiro = novoNo;
if (ultimo != null)
ultimo.prox = novoNo;
ultimo = novoNo;
}
void insereNo_inicio (IntNoSimples novoNo){
if (primeiro != null)
{novoNo.prox = primeiro;
primeiro = novoNo;
Técnico em Informática – Lógica de Programação e Estrutura de Dados 64
}
else
{if (primeiro == null)
primeiro = novoNo;
ultimo = novoNo;
}
}
int ContarNos(){
int tamanho = 0;
IntNoSimples temp_no = primeiro;
while (temp_no != null)
{tamanho++;
temp_no = temp_no.prox;
}
return tamanho;
}
void insereNo_posicao(IntNoSimples novoNo, int posicao){
IntNoSimples temp_no = primeiro;
int numero_nos = ContarNos();
int pos_aux;
if(posicao == 0)
{novoNo.prox = primeiro;
if(primeiro == ultimo)
{ultimo = novoNo;}
primeiro = novoNo;}
else
{if (posicao <= numero_nos)
{pos_aux = 1;
while(temp_no != null && posicao > pos_aux)
{temp_no = temp_no.prox;
pos_aux ++;
}
novoNo.prox = temp_no.prox;
temp_no.prox = novoNo;
Técnico em Informática – Lógica de Programação e Estrutura de Dados 65
}
else
{if(posicao > numero_nos)
{ultimo.prox = novoNo;
ultimo = novoNo;
}
}
}
}
IntNoSimples buscaNo (int buscaValor){
int i = 0;
IntNoSimples temp_no = primeiro;
while (temp_no != null)
{if (temp_no.valor == buscaValor)
{System.out.println ("No " + temp_no.valor + " posição " + i);
return temp_no;
}
i++;
temp_no = temp_no.prox;
}
return null;
}
void excluiNo (int valor){
IntNoSimples temp_no = primeiro;
IntNoSimples noAnterior = null;
while (temp_no.prox != null && temp_no.valor != valor)
{noAnterior = temp_no;
temp_no = temp_no.prox;
}
System.out.println(temp_no.valor + "proximo" + temp_no.prox.valor);
temp_no = noAnterior.prox.prox;
System.out.println(temp_no.valor + "proximo" + temp_no.prox.valor);
}
void exibeLista(){
Técnico em Informática – Lógica de Programação e Estrutura de Dados 66
class ListEncaSimples {
static ExeListaSimplesCompleta Slist = new ExeListaSimplesCompleta ();
int i = 0;
IntNoSimples temp_no;
int valor;
Slist.insereNo_fim(new IntNoSimples(valor));
break;
case 3 :
valor = Integer.parseInt (JOptionPane.showInputDialog(null, "Inserir um Nó em
uma posição \n" + "Digite um valor"));
posicao = Integer.parseInt (JOptionPane.showInputDialog(null, "Digite a
posição"));
Slist.insereNo_posicao(new IntNoSimples(valor),posicao);
break;
case 4:
valor = Integer.parseInt (JOptionPane.showInputDialog(null, "Localiza
um valor \n" + "Digite um valor"));
Slist.buscaNo(valor);
break;
case 5:
valor = Integer.parseInt (JOptionPane.showInputDialog(null, "Exlui um
nó da lista \n" + "Digite um valor"));
Slist.excluiNo(valor);
break;
case 6:
JOptionPane.showMessageDialog(null,"Exibe a lista");
Slist.exibeLista();
break;
default : JOptionPane.showMessageDialog(null,"Sair");
}
}
}
}
pois cada nó possui uma referência para o próximo elemento da lista e outra para o
anterior.
Criação do nó:
class IntNoDuplo {
int valor;
IntNoDuplo prox;
IntNoDuplo ant;
}
numero_nos--;
}
}
9.1.3. Filas
O conceito de fila em programação é o mesmo das filas dos nosso dia a dia, nas quais
esperamos ser atendidos em ordem: o primeiro elemento a entrar na fila será o primeiro
elemento a sair. Esse conceito é conhecido como first in, first out ou FIFO, expressão
conhecida em português como PEPS ou "primeiro que entra, primeiro que sai". Então, no
conceito de Fila, os elementos são atendidos, ou utilizados, sequencialmente, na ordem em
que são armazenados.
As filas (queues) são conjuntos de elementos (ou listas) cujas operações de inserção
são feitas por uma extremidade, e as de remoção, por outra.
Como exemplo, pode-se implementar uma fila de impressão, na qual os arquivos que
devem ser impressos são organizados em uma lista e serão impressos na ordem de chegada, à
medida que a impressora estiver disponível.
Podemos utilizar a para implementação das filas ou por objetos(referência). Primeiro
iremos utilizar os objetos (referência), utilizando para isto uma array. Para isto precisamos
construir um registro que contenha as informações da fila, como o início, o final e o contêiner
de elementos que é um vetor; neste caso cada um dos elementos da fila será representado por
uma posição no vetor. Veja a estrutura:
class Fila {
int tamanho;
int inicio;
int fim;
int total;
int vetor[];
Fila(int tam) {
inicio = 0;
fim = 0;
total = 0;
tamanho = tam;
vetor = new int [tam];
}
Técnico em Informática – Lógica de Programação e Estrutura de Dados 72
return elem;
}
}
public void exibeFila()
{for (int i = 0; i < total; i++)
{System.out.println("posicao " + i + " valor " + vetor[i]);
}
}
}
Vantagens:
•
A inserção ou remoção de um elemento na lista não implica a mudança de
lugar de outros elementos;
• Não é necessário definir, no momento da criação da lista, o número
máximo de elementos que esta poderá ter. Ou seja, é possível alocar
memória "dinamicamente", apenas para o número de nós necessários.
Desvantagens:
9.1.4. Pilhas
As pilhas também são conhecidas como lista LIFO ou PEPS. Trata-se de uma lista
linear em que todas as operações de inserção e remoção são feitas por um único extremo
denominado topo. Um exemplo bastante comum em que se aplica o conceito de pilhas é o de
uma pilha de pratos que estão guardados no armário: quando a pessoa utiliza um deles, pega
sempre o prato que se encontra no topo da pilha, assim como, quando um novo prato for
guardado, será colocado no topo. Isso acontece porque apenas uma das extremidades da pilha
está acessível.
Método pilha:
int topo;
Object vetor[];
pilha (int tam){
topo = -1;
tamanho = tam;
vetor = new Object [tam];
}
public boolean vazia(){
if(topo == -1)
return true;
else
return false;
}
import java.util.Scanner;
int opcao = 1;
while (opcao != 4){
System.out.println("Escolha uma Opção: ");
System.out.println("1 - Inserir um elemento na pilha:
");
System.out.println("2 - Excluir elemento da Pilha: ");
System.out.println("3 - Exibir elementos da fila: ");
System.out.println("4 - Sair: ");
opcao = input.nextInt();
switch (opcao){
case 1 :
System.out.println("Empilhar elemento \n" +
"Digite um Valor" );
valor = input.nextInt();
P.empilhar(valor);
break;
case 2 :
System.out.println("Empilhar desempilhado " +
P.desempilhar() );
break;
case 3 :
P.exibePilha();
break;
default:
System.out.println("Sair !");
break;
}
}
}
}
9.1.5. Árvores
class BIntNo{
int valor;
BIntNo esq, dir;
Uma árvore binária sempre possui nós com grau menor ou igual a 02, isto é, nenhum
nó possui mais do que dois descendentes diretos (dois filhos). Nesse tipo de árvore também
existe uma particularidade quanto à posição dos nós: os nós da direita sempre possuem valor
superior ao do nó pai, e os nós da esquerda sempre possuem valor inferior ao do nó pai.
class BArvore{
BIntNo Raiz;
private BIntNo inserir (BIntNo arvore, int novoNo){
if (arvore == null)
return new BIntNo(novoNo);
else
{if (novoNo < arvore.valor)
arvore.esq = inserir (arvore.esq, novoNo);
Técnico em Informática – Lógica de Programação e Estrutura de Dados 78
else
arvore.dir = inserir (arvore.dir, novoNo);
return arvore;}
}
public void inserirNo (int novoValor){
Raiz = inserir (Raiz, novoValor);
}
private void exibir_esquerdo (BIntNo arv){
if (arv != null){
exibir_esquerdo (arv.esq);
System.out.println (arv.valor);
}}
private void exibir_direito (BIntNo arv){
if (arv != null){
exibir_direito (arv.dir);
System.out.println (arv.valor);
}
}
public void exibir_raiz()
{System.out.println("Raiz " + Raiz.valor);
}
public void exibirNo_esq (){
exibir_esquerdo (Raiz);
}
public void exibirNo_dir (){
exibir_direito (Raiz);
}
public void excluirNo (int item){
try{
BIntNo tempNo = Raiz, pai = null, filho = Raiz, temp;
while (tempNo != null && tempNo.valor != item){
pai = tempNo;
if (item < tempNo.valor)
tempNo = tempNo.esq;
Técnico em Informática – Lógica de Programação e Estrutura de Dados 79
else
tempNo = tempNo.dir;
}
if (tempNo == null)
System.out.println ("Item nao localizado.");
if (pai == null){
if (tempNo.dir == null)
Raiz = tempNo.esq;
else
if (tempNo.esq == null)
Raiz = tempNo.dir;
else{
for (temp = tempNo, filho = tempNo.esq;
filho.dir != null; temp = filho, filho = filho.dir);
if (filho != tempNo.esq){
temp.dir = filho.esq;
filho.esq = Raiz.esq;
}
filho.dir = Raiz.dir;
Raiz = filho;
}
} else if (tempNo.dir == null){
if (pai.esq == tempNo)
pai.esq = tempNo.esq;
else
pai.dir = tempNo.esq;
} else if (tempNo.esq == null){
if (pai.esq == tempNo)
pai.esq = tempNo.dir;
else
pai.dir = tempNo.dir;
} else {
for (temp = tempNo, filho = tempNo.esq;
filho.dir != null; temp = filho, filho = filho.dir);
Técnico em Informática – Lógica de Programação e Estrutura de Dados 80
if (filho != tempNo.esq){
temp.dir = filho.esq;
filho.esq = tempNo.esq;
}
filho.dir = tempNo.dir;
if (pai.esq == tempNo)
pai.esq = filho;
else
pai.dir = filho;
}
} catch (NullPointerException erro) {
//Item nao encontrado
}
}
}
Utilização do código acima:
class usaArvore{
public static void main(String[] args){
BArvore arvore1 = new BArvore ();
arvore1.inserirNo (14);
arvore1.inserirNo (16);
arvore1.inserirNo (12);
arvore1.inserirNo (11);
arvore1.inserirNo (17);
arvore1.inserirNo (15);
arvore1.exibirNo_esq();
arvore1.exibirNo_dir();
arvore1.inserirNo (10);
arvore1.inserirNo (13);
arvore1.exibir_raiz();
System.out.println ("Nós a esquerda ");
arvore1.exibirNo_esq();
System.out.println ("Nós a direita ");
Técnico em Informática – Lógica de Programação e Estrutura de Dados 81
arvore1.exibirNo_dir();
System.out.println("Exclusão de nó");
arvore1.excluirNo(12);
arvore1.exibir_raiz();
System.out.println ("Árvore após a exclusão do nó de valor 12");
System.out.println ("Nós a esquerda ");
arvore1.exibirNo_esq();
System.out.println ("Nós a direita ");
arvore1.exibirNo_dir();
}
}
Técnico em Informática – Lógica de Programação e Estrutura de Dados 82
10. Bibliografia
Puga, Sandra; issetti, Gerson. Lógica de programação e estrutura de dados com aplicações em
Java. 2ª ed, São Paulo: Pearson,2009.
T. Goodrich, Michael; Tamassia, Roberto. Estruturas de dados e Algoritmos em Java. 4ª ed,
São Paulo: Bookman, 2006.
http://www.gforum.tv/board/1345/120437/manual-java-arrays-em-java.html
http://pt.wikipedia.org/wiki/Fatorial