Posted on 09:55, fevereiro 19th, 2008 by Prof. Luis Eduardo

Sejam bem vindos, esta é a décima quinta aula de Programação Web em Java, para saber mais sobre o curso, começe em Curso de Programação Web em Java - CPWJ

Vamos construir uma aplicação de verdade usando Java e Web e o modelo MVC. Já sabemos lidar com java, xhtml e css e um pouco de teoria sobre o MVC. Vamos colocar tudo pra funcionar?

Definindo o que será nosso primeiro programa: um sistema de busca. Vamos começar com um formulário simples com uma caixa de texto e um botão buscar, que quando clicado leva a outra página com a lista de sites com a palavra chave procurada.

Eu prometi que o conteúdo seria apresentado com o banco de dados mysql, porém tive uma seqüência de problemas com o hibernate mais mysql. Não quiz perder tempo com os detalhes. Eu não trabalho com o mysql, mas com o Oracle. Acredito que vocês possam encontrar material sobre o uso do mysql e hibernate, porém eu estou com pressa para publicar logo este material e como tenho experiência com Oracle é com ele mesmo que vou continuar. A forma de trabalho é a mesma, mudando apenas o xml de conexão com o banco.

Para uso do Oracle faça o download do Oracle 10g Express Edition em http://www.oracle.com/technology/software/products/database/index.html. É uma versão limitada mas de uso gratuíto. (Debian, Mandriva, Novell, Red Hat, Ubuntu e Windows compatíveis conforme o site Oracle).

Após o processo de instalação crie um usuário “sbusca” com senha “suasenha”.

É só o que você precisa na parte do banco de dados, o restante ficará por conta do Hibernate.

Para a configuração do ambiente do Netbeans 6.0, você precisa das seguintes arquivos de biblioteca:

  • para conectar no banco:
    • classes12.jar
  • para o Hibernate:
    • ant-antlr-1.6.5.jar
    • asm-attrs.jar
    • asm.jar
    • cglib-2.1.3.jar
    • commons-collections-2.1.1.jar
    • commons-logging-1.0.4.jar
    • dom4j-1.6.1.jar
    • ehcache-1.2.3.jar
    • hibernate3.jar
    • jta.jar

O classes12.jar você encontra aqui mesmo:jdbc Oracle. As bibliotecas do Hibernate você encontra no site do Hibernate em http://www.hibernate.org/6.html. A opção de download do Core é suficiente. (hibernate3.jar está na raiz do zip e os outros no diretório lib)

Reserve os arquivos indicados acima, somente eles, em um diretório qualquer de sua máquina.

Abra agora o Netbeans e vamos começar a fazer a mágica. Após o processo de carga escolha o opção File/New Project…

Escolha a Categoria Web e o tipo de projeto Web Application conforme a figura abaixo:
Novo Projeto

Clique em Next e digite o nome do projeto e se quiser escolha outra localização para a pasta do projeto. O restante pode deixar como indicado na tela:
Novo Projeto (2)

Clique em Next e ative a biblioteca do Struts conforme a figura:
Novo Projeto (3)

Clicando em Finish o projeto estará criado.

Vamos instalar as bibliotecas hibernate e do oracle para uso no nosso projeto. Na aba Projects use o botão direito sobre o nome do projeto (sbusca) e clique em properties. Na janela “Project Properties - sbusca” clique em libraries nas Categorias e no botão “Add JAR/Folder”. Selecione todos os arquivos do diretório que você colocou os arquivos jar e confirme clicando em “OK”.

Criado o projeto e definido as bibliotecas que vamos utilizar, o próximo passo é o Hibernate. Esta biblioteca auxilia no acesso ao Banco de Dados. Implementa a persistência aos objetos, fazendo a ponte objeto/relacional.

Vamos configurar o Hibernate para conexão com o Oracle. Para isso vamos escrever um arquivo de configuração XML. Clique com o botão direito do mouse sobre “Source Package” na aba do projeto e escolha a opção “New/ XML Document”. Digite o nome do arquivo como “hibernate.cfg.xml” (xml é automaticamente preenchido digite somente hibernate.cfg). Clique em “Next” e “Finish”.

Digite ou copie o código de configuração da conexão com o Oracle: (sempre cuidado com as aspas em códigos fonte, o WordPress detona lembra-se?)

<?xml version=’1.0′ encoding=’utf-8′?>
<!DOCTYPE hibernate-configuration
PUBLIC “-//Hibernate/Hibernate Configuration DTD 3.0//EN”
“http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd”>

<hibernate-configuration>

<session-factory>

<!– Database connection settings –>

<property name=”connection.driver_class”>oracle.jdbc.driver.OracleDriver</property>

<property name=”connection.url”>jdbc:oracle:thin:@10.89.9.6:1521:orabkl</property>

<property name=”connection.username”>SBUSCA</property>

<property name=”connection.password”>suasenha</property>

<!– JDBC connection pool (use the built-in) –>

<property name=”connection.pool_size”>1</property>

<!– SQL dialect –>

<!–property name=”dialect”>org.hibernate.dialect.HSQLDialect</property–>

<property name=”dialect”>org.hibernate.dialect.Oracle9Dialect</property>

<!– Enable Hibernate’s automatic session context management –>

<property name=”current_session_context_class”>thread</property>

<!– Disable the second-level cache –>

<property name=”cache.provider_class”>org.hibernate.cache.NoCacheProvider</property>

<!– Echo all executed SQL to stdout –>

<property name=”show_sql”>true</property>

<!– Drop and re-create the database schema on startup –>

<!– Depois que executar uma vez a classe de teste elimine a linha seguinte. Esta linha provoca a exclusão de todas as tabelas e recriação.–>

<property name=”hbm2ddl.auto”>create</property>

<mapping resource=”sbusca/Sites.hbm.xml”/>

</session-factory>

</hibernate-configuration>

Para facilitar a codificação com o Hibernate vamos criar uma classe para a conexão e desconexão do banco de dados. Clique com o botão direito do mouse sobre “Source Package” na aba do projeto e escolha a opção “New\java class”. Chame a classe de “HibernateUtil” e defina o package como “util”:
HibernateUtil

Clique em finish e copie o código da classe:

package util;

import org.hibernate.*;

import org.hibernate.cfg.*;

public class HibernateUtil {

private static final SessionFactory sessionFactory;

static {

try {

// Create the SessionFactory from hibernate.cfg.xml

sessionFactory = new Configuration().configure().buildSessionFactory();

} catch (Throwable ex) {

// Make sure you log the exception, as it might be swallowed

System.err.println(”Initial SessionFactory creation failed.” + ex);

throw new ExceptionInInitializerError(ex);

}

}

public static SessionFactory getSessionFactory() {

return sessionFactory;

}

}

Com a biblioteca carregada e as configurações do hibernate certas, vamos codificar uma classe Sites para representar um dado persistente. Clique em File/New File e escolha Categoria “java” e “File Types” igual a “Java Class”:

Nova Classe

Clique em “Next” e defina o nome da classe como Sites e o package como sbusca:

Nova Classe (2)

Clicando em “Finish” o Netbeans irá abrir a página com o código da Classe. Complete o código da classe criando os campos necessários:

package sbusca;

public class Sites {

private Long id;

private String nome;

private String url;

private String descricao;

private String keyword;

public Sites() {}

public Long getId() {

return id;

}

private void setId(Long id) {

this.id = id;

}

public String getNome() {

return nome;

}

public void setNome(String nome) {

this.nome = nome;

}

public String getUrl() {

return url;

}

public void setUrl(String url) {

this.url = url;

}

public String getDescricao() {

return descricao;

}

public void setDescricao(String descricao) {

this.descricao = descricao;

}

public String getKeyword() {

return keyword;

}

public void setKeyword(String keyword) {

this.keyword = keyword;

}

}

Para o funcionamento perfeito do Hibernate são necessários alguns detalhes:

  • Um campo Id para ser usado como campo chave automático;
  • Funções Get e Set públicos para manipulação dos dados privados;

Após a criação da classe é necessário definir um arquivo de mapeamento Hibernate. Com o botão direito do mouse sobre “sbusca” em destaque na figura, escolha a opção “new” e “others”.
Conectando Hibernate

Na janela “New File” escolha a categoria “XML” e “File Type” “Xml Document”. Clique em “Next” e defina o nome do arquivo como “Sites.hbm.xml” (a extensão xml é automaticamente inserida). Clique em “Next” e por fim em “Finish”. Copie o código abaixo para realizar a amarração:

<?xml version=”1.0″?>

<!DOCTYPE hibernate-mapping PUBLIC

“-//Hibernate/Hibernate Mapping DTD 3.0//EN”

“http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd”>

<hibernate-mapping>

<class name=”sbusca.Sites” table=”SITES”>

<id name=”id” column=”SITES_ID”>

<generator class=”native”/>

</id>

<property name=”nome”/>

<property name=”url”/>

<property name=”descricao”/>

<property name=”keyword”/>

</class>

</hibernate-mapping>

Para verificar se tudo funcionou até aqui, vamos criar uma classe para ver se o hibernate está conseguindo criar os registros: (espero que já saiba como criar a classe depois de eu repetir mais de uma vez a seqüencia de teclas!)

package sbusca;

import org.hibernate.Session;

import util.HibernateUtil;

public class MaquinaDeBusca {

public static void main(String[] args) {

MaquinaDeBusca mgr = new MaquinaDeBusca();

mgr.createAndStoreEvent(”Tecnoclasta”,”http://www.tecnoclasta.com”,”Detonanto Tecnologia”,”java, tecnologia, astronáutica, astronomia”);

mgr.createAndStoreEvent(”Uol Universo On-line”,”http://www.uol.com.br/“,”Universo On-line - O maior portal em língua portuguesa”,”portal, uol, sites, notícias”);

mgr.createAndStoreEvent(”Portal Terra”,”http://www.terra.com.br/“,”Qual a sua Terra”,”portal, terra, notícias, sites”);

mgr.createAndStoreEvent(”Folha de São Paulo”,”http://www.folha.uol.com.br/“,”O Jornal com Credibilidade”,”jornal, folha, notícias”);

HibernateUtil.getSessionFactory().close();

}

private void createAndStoreEvent(String nome, String url,

String descricao, String keyword) {

Session session = HibernateUtil.getSessionFactory().getCurrentSession();

session.beginTransaction();

Sites umSite = new Sites();

umSite.setNome(nome);

umSite.setDescricao(descricao);

umSite.setUrl(url);

umSite.setKeyword(keyword);

session.save(umSite);

session.getTransaction().commit();

}

}

Executando esta classe o NetBeans vai trabalhar um bocado, e no fim do processo tudo deverá funcionar. Veja você mesmo se foi criada a tabela e se os registros foram criados corretamente.

Observe que o hibernate elimina toda a necessidade de codificação em SQL. Isso facilita muito a manutenção e mesmo portar o sistema para um banco de dados diferente.

Um segundo teste do hibernate consiste em executar uma consulta. Mude a função main para esta, inclua uma nova função “buscaSites()” e execute a classe novamente:

public static void main(String[] args) {

MaquinaDeBusca mgr = new MaquinaDeBusca();

//String teste=”store”;

String teste = “list”;

if (teste.equals(”store”)) {

mgr.createAndStoreEvent(”Tecnoclasta”, “http://www.tecnoclasta.com”, “Detonanto Tecnologia”, “java, tecnologia, astronáutica, astronomia”);

mgr.createAndStoreEvent(”Uol Universo On-line”, “http://www.uol.com.br”, “Universo On-line - O maior portal em língua portuguesa”, “portal, uol, sites, notícias”);

mgr.createAndStoreEvent(”Portal Terra”, “http://www.terra.com.br”, “Qual a sua Terra”, “portal, terra, notícias, sites”);

mgr.createAndStoreEvent(”Folha de São Paulo”, “http://www.folha.uol.com.br”, “O Jornal com Credibilidade”, “jornal, folha, notícias”);

} else if (teste.equals(”list”)) {

List sites = mgr.buscaSites(”notícias”);

for (int i = 0; i < sites.size(); i++) {

Sites umSite = (Sites) sites.get(i);

System.out.println(”Site: ” + umSite.getNome() +

“: ” + umSite.getDescricao()+ “, Url:”+umSite.getUrl());

}

}

HibernateUtil.getSessionFactory().close();

}

public List buscaSites(String keyword) {

Session session = HibernateUtil.getSessionFactory().getCurrentSession();

session.beginTransaction();

List result = session.createQuery(”from Sites where keyword like ‘”+ keyword+”‘”).list();

session.getTransaction().commit();

return result;

}

Dando certo será listado os sites da Uol, Terra e Folha.

Pensei em fazer isso em uma aula só, porém está ficando muito, muito longo. Então fica aqui a primeira parte do sistema de busca. Na próxima aula terminamos.

Dúvidas? vá para o fórum.

Posted on 08:54, fevereiro 14th, 2008 by Prof. Luis Eduardo

Sejam bem vindos, esta é a décima quarta aula de Programação Web em Java, para saber mais sobre o curso, começe em Curso de Programação Web em Java - CPWJ.

Até a última aula de HTML e CSS descobrimos como preparar uma página para publicação na Internet. Porém estas página preparadas assim tem um problema: são estáticas. Uma vez escritas e copiadas para o servidor, permanecerão exatamente iguais em todos os detalhes.

Com o conteúdo de Java aprendemos como construir programas. Vamos juntar as duas coisas agora.

JSP é uma sigla para Java Server Pages, e é uma tecnologia desenvolvida pela Sun para permitir o uso do Java para produzir páginas dinâmicas na Web. É utilizada em conjunto com classes Java com regras específicas para atendimento a requisições dos usuários. Estas classes são os Servlets.

Revisando como funciona a Web

O cliente faz uma requisição através do navegador quando:

  • Digita um endereço na barra de endereço e envia;
  • Clica em um botão de envio de um formulário;
  • Modifica um dado em um formulário com código javascript relacionado;

Na ação do usuário esta requisição é enviada pela Internet (ou Intranet) até o servidor de Web e este faz uma série de ações:

  • Interpreta a requisição
  • Procura na pasta root o arquivo HTML pedido
  • Envia o arquivo de volta ao navegador do cliente

Por fim o navegador do cliente interpreta o código Html, css e “desenha” o resultado.

Páginas dinâmicas

Com as páginas dinâmicas a diferença está nas ações do servidor de WEB:

  • Interpreta a requisição e detectando um pedido para página dinâmica:
  • Aciona uma classe Servlet
  • A classe Servlet interpreta qual ação foi requisitada e aciona as classes adequadas
  • Após a execução das ações, é chamada a página JSP para preparar a resposta visuais à requisição. As páginas JSP possuem código para produção de uma página HTML ad-roc, isto é sob demanda.
  • O Servidor envia para o navegador cliente a página de resposta gerada

Observe que temos duas camadas de código para produção de uma página dinâmica: os Servlets e o JSP. Um modelo mais completo utiliza três camadas e é chamada MVC Model-View-Control. Vamos ver cada uma destas camadas:

Model

A camada Model (modelo) possui a representação das informações do programa. No nosso exemplo, esta camada irá implementar classes para representar as entidades envolvidas no programa. Por exemplo em um programa de frente de caixa, haveria classes para representar produtos, compras, notas fiscais, itens de notas fiscais, métodos de pagamento. Estas classes iriam também armazenar todas as ações que eventualmente o usuários necessitasse realizar sobre estas entidades. Normalmente as classes utilizam um sistema de banco de dados para fazer o armazenamento persistente. Utilizaremos a biblioteca Hibernate para facilitar a persistência dos dados. Iremos utilizar o banco de dados Mysql para os exemplos

View

A camada View (visão) é responsável por construir uma interface para interação do usuário. Ela prepara a apresentação da informação para que o usuário possa reagir as respostas e continuar utilizando o programa. Em Java utilizaremos páginas JSP com Jstl para produzir as páginas de resposta. Observe que a camada View não acessa diretamente o banco de dados, ela recebe normalmente objetos Collection geradas pelas classes da camada Model e produz código HMTL a partir deles. Percebeu porque tivemos uma longa aula sobre coleções? (revise)

Control

A camada Control (controle) é a camada que controla o processo. Cada requisição do usuário é primeiro interpretado pela camada de controle que determina qual ação deve ser executada no modelo e encaminha depois a resposta do modelo para a camada de visão. No nosso exemplo quem irá fazer toda a camada de controle será o Struts.

Preparem-se, na próxima aula um sistema de busca completo será nosso primeiro programa!

Arrumem suas máquinas:

Dúvidas? vá para o fórum.

Posted on 23:20, janeiro 29th, 2008 by Prof. Luis Eduardo

Sejam bem vindos, esta é a décima terceira aula de Programação Web em Java, para saber mais sobre o curso, começe em Curso de Programação Web em Java - CPWJ.

Hoje a aula é bem curta e semana que vem é carnaval e teremos folga. Aproveite para adiantar nas aulas e conseguir acompanhar o ritmo. Vamos falar de Exceções ou tratamento de erros em Java.

O sistema de exceções do Java é uma ferramenta para ajudar os programadores a reportar e manipular erros.

Sempre que uma função chamada em um programa puder gerar uma exceção o programador é obrigado a tomar uma ação. Esta ação pode ser a captura e tratamento do erro, ou simplesmente o lançamento do erro para outra função tratar. Vamos ver primeiro como tratar o erro:

Exemplo de tratamento/captura de erro típico: (Exception Catch)

public float dividir(int a, int b) {
Float resultado;
float r=0;
try { // Bloco try delimita a porção de código que pode apresentar erro
resultado = new Float(a / b);
r=resultado.floatValue(); //divisão executada armazena resultado
} catch (ArithmeticException e) { //bloco catch trata o tipo de exceção indicado
return 0; //divisão por zero
} catch (Exception x) { //são permitidos vários blocos catch, um para cada tipo de exceção.
//Exception é usada para qualquer tipo de exceção não específica encontrada
//tratar aqui outros erros
} finally { // é executada após o tratamento das exceções ou quando nenhuma exceção
//é gerada normalmente quando é liberado os recursos usados na função
resultado = null;
System.out.println(r);
}
// após a execução das exceções ou de todo o bloco try, o fluxo prossegue deste ponto
return r;
}
}

Lançamento de Exceções (Exception throwing)

Neste caso a função lança exceções para a função chamadora, isso é, quem deverá capturar o erro e tratá-lo é uma função que usa esta função para funcionar. Em outras palavras, a função escrita não trata o erro, simplesmente avisa que o erro aconteceu e interrompe seu processamento.

Exemplo de lançamento de erro:

public class File {
public File(String nomeArquivo) throws FileNotFoundException {

if (arquivo não encontrado ) {
throw new FileNotFoundException();
}
}
}

“throws FileNotFoundException” na linha de declaração da função, indica que nesta função este tipo de exceção poderá ocorrer. Isso obriga o programador que usar esta função a tratar esta exceção (ou lançar para outro nível novamente).

“throws new FileNotFoundException();” indica que uma exceção foi detectada e avisa a máquina Java a respeito.

E por hoje é só.

Na Seqüência

  • dia 5 de Fevereiro: Carnaval. (não esqueçam a camisinha moçada!)
  • dia 12 de Fevereiro: Introdução a Jsp.

Dúvidas? vá para o fórum.

Procure os mais baratos Livros sobre a Web, Livros sobre Java, Livros HTML ou Livros CSS nas melhores lojas do Brasil.

Posted on 19:25, janeiro 22nd, 2008 by Prof. Luis Eduardo

Sejam bem vindos, esta é a décima segunda aula de Programação Web em Java, para saber mais sobre o curso, começe em Curso de Programação Web em Java - CPWJ.

Estamos retornando hoje das férias e continuando a todo vapor com o curso. A partir de hoje fique atento, que as aulas voltarão todas as terças-feiras. O conteúdo de Java está no final, logo iremos começar nossa primeira aplicação Web com JSP.

Hoje iremos aprender alguns conceitos e técnicas para trabalhar com coleções.

Hashing

Hashing é uma maneira de identificar objetos com um número inteiro. Coisas iguais tem (ou deveriam ter) o mesmo número hash. Isso é extremamente útil para realização de comparações mais rápidas.

Em classes escritas por você mesmo, para isso funcionar corretamente, você deve sobrescrever a função .hashCode() e gerar seu próprio número hash.

A função .HashCode()

Esta função deve retornar um número inteiro. É definida na classe java.lang.Object e retorna altomaticamente um valor único para cada instância (para cada objeto).

Se sua classe tem comportamento diferente deste, você deve sobrescrever esta função.

As três premissas da função .HashCode() são:

  • O hashCode de um objeto não deve mudar se o valor de um objeto não mudar.
  • Dois objetos iguais DEVEM ter o mesmo hashCode
  • É desejável que dois objetos diferentes tenham hashCode distintos (sempre que isso for possível)

Exemplos de hashCode:

String scott = “Scotty”;

String scott2 = “Scotty”;

String corey = “Corey”;

System.out.println(scott.hashCode());

System.out.println(scott2.hashCode());

System.out.println(corey.hashCode());

=> -1823897190, -1823897190, 65295514

Integer int1 = 123456789;

Integer int2 = 123456789;

System.out.println(int1.hashCode());

System.out.println(int2.hashCode());

=> 123456789, 123456789

Classe NomeCompleto

Para prosseguir iremos definir uma classe chamada NomeCompleto, que será utilizada nos exemplos do restante da aula:

public class NomeCompleto {

public String nome;

public String sobrenome;

public NomeCompleto(String nome, String sobrenome) {

this.nome = nome;

this.sobrenome = sobrenome;

}

public String toString() {

return nome + ” ” + sobrenome;

}

public boolean equals(Object o) {

return (o instanceof NomeCompleto &&

((NomeCompleto) o).nome.equals(this.nome) &&

((NomeCompleto) o).sobrenome.equals(this.sobrenome));

}}

Vamos verificar se esta classe NomeCompleto está funcionando corretamente:

NomeCompleto maria = new NomeCompleto(”Maria”, “Lúcia”);

NomeCompleto jose = new NomeCompleto(”José”, “Silva”);

NomeCompleto jose2 = new NomeCompleto(”José”, “Silva”);

System.out.println(maria.equals(jose));

System.out.println(jose.equals(jose2));

System.out.println(maria.hashCode());

System.out.println(jose.hashCode());

System.out.println(jose2.hashCode());

⇒ false, true, 6718604, 7122755, 14718739

Objetos são iguais, mas o hashCode não é. Precisamos arrumar esta classe.

Você não pretende usar a classe hashCode, portanto não precisa se preocupar com isso não é? ERRADO! Você precisa resolver isso porque irá ter problemas com listas e coleções. As classes que implementam as listas pressupõem que a função hashCode() funciona corretamente.

Aliás, estamos vendo hashCode no início desta aula, justamente para podermos usar listas na continuação, e lembrá-lo que antes de usar listas deve sobrescrever esta função.

O que deve fazer a função hashCode mesmo? Gerar um número inteiro único para objetos com conteúdo iguais, e diferentes para objetos de conteúdo diferente.

Possível implementação para o nosso exemplo:

public class NomeCompleto {

public int hashCode() {

return nome.hashCode() *23

+ sobrenome.hashCode();

}

}

Veja que as classes String já implementam hashCode corretamente. Usamos “*23″ para que José Maria seja diferente de Maria José. Faça testes e verifique que sem a multiplicação o hashCode gerado é o mesmo.

Tenha certeza que entendeu este tópico antes de prosseguir. Funções hashCode não implementadas ou com código errado irão provocar problemas estranhos no uso de coleções. Estes problemas poderão te deixar realmente confuso. Se tiver dúvidas nesta parte pergunte no fórum, ou nos comentários antes de continuar.

Coleções

Coleções são implementações da biblioteca java para executar:

  • Coleções de objetos
  • Ordenação de objetos
  • Estocagem de objetos
  • Recuperação e busca de objetos estocados

Para usar Coleções deve-se incluir a importação de java.util.* no topo de cada arquivo *.java:

package lab2;

import java.util.*;

public class UsandoColecoes {

List<String> lista = new ArrayList<String>();

… //resto da classe

}

Sintaxe básica de uma coleção de NomeCompleto:

  • Adiciona um nome a lista: boolean add(NomeCompleto o);
  • Verifica se um objeto está na lista: boolean contains(Object o);
  • Remove um elemento da lista: boolean remove(NomeCompleto o);
  • Verifica quantos elementos tem na lista: int size();

Exemplo de uso:

List<NomeCompleto> iapjava = new ArrayList<NomeCompleto>();

iapjava.add(new NomeCompleto(”Luis”, “Lima”);

iapjava.add(new NomeCompleto(”José”, “Silva”);

System.out.println(iapjava.size()); => 2

iapjava.remove(new NomeCompleto(”José”, “Silva”);

System.out.println(iapjava.size()); => 1

List<NomeCompleto> iapruby = new ArrayList<NomeCompleto>();

Iapruby.add(new NomeCompleto(”Marcos”, “Fontes”));

iapjava.addAll(iapruby);

System.out.println(iapjava.size()); => 2

Coleções Genéricas

É permitido definir uma coleção que só armazene objetos de um determinado tipo como no exemplo acima. Porém também é permitido definirmos coleções genéricas que armazenam objetos de qualquer tipo.

Exemplo de coleções genéricas:

List untyped = new ArrayList();

List<String> typed = new ArrayList<String>();

 

Object obj = untyped.get(0);

String sillyString = (String) obj;

String smartString = typed.get(0);

As coleções não genéricas ou tipadas são mais práticas de manipular.

Recuperando todos os dados de uma lista:

Dado uma coleção de NomeCompleto chamada “colecaox” podemos usar duas ferramentas para recuperar cada item da coleção: Iterator e For each.

Iterator

Iterator<NomeCompleto> it = colecaox.iterator();

while (it.hasNext) {

NomeCompleto obj = it.next();

// Fazer alguma coisa com cada objeto

}

For each

for (NomeCompleto obj : colecaox) {

// Fazer alguma coisa com cada objeto

}

 

Excluir objetos da lista enquanto se está recuperando os mesmo:

Não é permitido remover objetos de uma coleção enquanto a mesma está em um laço for-each. Para remover uma lista enquanto se está recuperando é necessário usar o Iterator:

Iterator<NomeCompleto> it = colecaox.iterator();

while (it.hasNext) {

NomeCompleto obj = it.next();

it.remove(obj); // Veja que só se remove pelo Iterator não pela coleção: colecaox.remove(Obj);

}

Tipos de Coleção disponíveis:

  • Listas:
    • ArrayList;
  • Conjunto: (set)
    • HashSet
    • TreeSet
  • Mapeamento (map)
    • HashMap

Listas

ArrayList é uma lista de objetos ordenados, similar a um Array, porém sem tamanho pré-definido. A lista é ordenada de acordo com a ordem de inserção.

Definindo e inserindo itens na lista:

List<String> strings = new ArrayList<String>();

strings.add(”one”);

strings.add(”two”);

strings.add(”three”);

// strings = [ "one", "two", "three"]

Inserindo objetos em uma determinada posição

List<String> strings = new ArrayList<String>();

strings.add(”one”);

strings.add(”three”);

strings.add(1, “two”);

// strings = [ "one", "two", "three"]

Recuperando objetos de uma determinada posição:

s.o.print(strings.get(0)) // => “one”

s.o.print(strings.indexOf(”one”)) // => 0

Conjuntos (set)

Coleção sem tamanho e sem ordem definida. Não é permitido duplicidade de objetos no conjunto.

Exemplo:

Set<NomeCompleto> nomes = new HashSet<NomeCompleto>();

nomes.add(new NomeCompleto(”José”, “Silva”));

nomes.add(new NomeCompleto(”José”, “Silva”));

System.out.println(names.size()); => 1

Regra de ouro para Conjuntos (set):

Um elemento do conjunto não pode mudar se isso poderá afetá-la a ponto de torná-lo igual a um outro objeto do conjunto. (ou a outro objeto a ser inserido no conjunto mesmo após a mudança)

Se não respeitar esta regra, pode se preparar para coisas realmente estranhas. De preferência sempre use objetos imutáveis com conjuntos.

Mapas (map)

Mapas são conjuntos de pares Chave/Valor. Para cada chave o mapa armazena um valor correspondente. Com o valor da chave a coleção map pode recuperar o valor previamente armazenado. Uma chave deve ser única, porém valores podem repetir.

É um serviço muito útil para armazenamento e posterior recuperação de dados com valor chave. Utilíssimo para uso com banco de dados relacionais. Iremos usar isso muito, então não deixe dúvidas a respeito

Mapas não implementam as funções add e contais, em seu lugar temos as seguintes funções:

  • boolean put(Foo chave, Bar valor);
  • boolean contaisKey(Foo chave);
  • boolean contaisvalue(Bar value);

(neste exemplos Foo e Bar são duas classes de qualquer tipo)

Exemplo de uso:

Map<String, String> dns = new HashMap<String, String>();

dns.put(”scotty.mit.edu”, “18.227.0.87″);

System.out.println(dns.get(”scotty.mit.edu”));

System.out.println(dns.containsKey(”scotty.mit.edu”));

System.out.println(dns.containsValue(”18.227.0.87″));

dns.remove(”scotty.mit.edu”);

System.out.println(dns.containsValue(”18.227.0.87″));

// => “18.227.0.87″, true, true, false

Outros métodos úteis em mapas (map):

  • keySet() - retorna um Set de todos as chaves
  • values() - retorna uma Collection de todos os valores (use ArrayList ou Set para armazená-lo)
  • entrySet() - returna um Set de pares “chave,valor”. Cada par é um objeto Map.Entry. Map.Entry suporta getKey, getValue, setValue ;

Comparação e Ordenação

Para uso das coleções ordenadas é preciso também definirmos a função compareTo nas classes que definirmos. Esta função é usada para decidir, entre dois objetos, qual é o maior ou se são iguais.

(a.compareTo(b)) deverá resultar em um número menor que zero se a < b, em zero se a = b e, finalmente, em um número maior que zero se a > b .

Exemplos de comparação:

Integer um = 1;

System.out.println(um.compareTo(3));

System.out.println(um.compareTo(-50));

String jose= “José”;

System.out.println(jose.compareTo(”Ana”));

System.out.println(jose.compareTo(”Zé”));

// => -1 , 1, 4, -2

Veja que as classes String e Integer já implementam uma função compareTo corretamente. Nas classes definidas pelo programador esta função deverá ser definida corretamente. Mais a frente iremos definí-la para nosso exemplo NomeCompleto. Por enquanto vamos ver como usar compareTo com listas para ordenar alfabeticamente uma lista:

List<String> nomes = new ArrayList<String>();

nomes.add(”Sailor”);

nomes.add(”Lula”);

nomes.add(”Bobby”);

nomes.add(”Santos”);

nomes.add(”Dell”);

Collections.sort(nomes);

// nomes => [ "Bobby", "Dell", "Lula", "Sailor", "Santos" ]

Interface Comparable

Podemos usar Colletions.sort com a lista acima porque Strings implementam Comparable. Isto é, Strings tem uma ordem natural. Para que uma classe NomeCompleto seja “Comparable”, você deve implementar:

int compareTo(NomeCompleto obj);

Exemplo:

public class NomeCompleto implements Comparable<NomeCompleto> {

public int compareTo(NomeCompleto o) {

int compare = this.sobrenome.compareTo(o.sobrenome)

if (compare != 0)

return compare;

else return this.nome.compareTo(o.nome);

}

}

Usando a nova classe Comparable NomeCompleto:

List<NomeCompleto> nomes = new ArrayList<NomeCompleto>();

nomes.add(new NomeCompleto(”Nicolas”, “Cage”));

nomes.add(new NomeCompleto(”Laura”, “Dern”));

nomes.add(new NomeCompleto(”Harry”, “Stanton”));

nomes.add(new NomeCompleto(”Diane”, “Ladd”));

nomes.add(new NomeCompleto(”William”, “Morgan”));

nomes.add(new NomeCompleto(”Dirty”, “Glover”));

nomes.add(new NomeCompleto(”Johnny”, “Cage”));

nomes.add(new NomeCompleto(”Metal”, “Cage”));

System.out.println(nomes);

Collections.sort(nomes);

System.out.println(nomes);

// => [Johnny Cage, Metal Cage, Nicolas Cage, Laura Dern, Crispin Glover,

Diane Ladd, William Morgan, Harry Stanton]

Objetos Comparadores (Comparator)

Para criar mais de um método de ordenação você deve definir classes Comparadoras. A classe comparadora simplesmente é uma classe com a implementação da função compateTo entre dois objetos:

int compare(Foo o1, Foo o2);

Exemplo de Comparador, ordenando primeiro nome primeiro:

public class PrimeiroNomePrimeiro implements

Comparator<NomeCompleto> {

public int compare(Nome n1, Nome n2) {

int ret = n1.nome.compareTo(n2.nome);

if (ret != 0)

return ret;

else return n1.sobrenome.compareTo(n2.sobrenome);

}

}

Isso deverá ser feito em arquivo separado do NomeCompleto.java: PrimeiroNomePrimeiro.java

Para usar o Comparador:

List<NomeCompleto> nomes = new ArrayList<NomeCompleto>();

.. .

Comparator<NomeCompleto> primeiroNome = new PrimeiroNomePrimeiro();

Collections.sort(nomes, primeiroNome);

System.out.println(nomes);

// => [Crispin Glover, Diane Ladd, Harry Stanton, Johnny

Cage, Laura Dern, Metal Cage, Nicolas Cage, William

Morgan]

Outra maneira de ordenar é usando TreeSet. Isso faz a ordenação de maneira automática, sem precisar chamar a função sort. Para funcionar os objetos da TreeSet devem ser “Comparable” ou você deve definir uma classe Comparator.

SortedSet<NomeCompleto> nomes = new TreeSet<NomeCompleto>(new PrimeiroNomePrimeiro());

nomes.add(new NomeCompleto(”Laura”, “Dern”));

nomes.add(new NomeCompleto(”Harry”, “Stanton”));

nomes.add(new NomeCompleto(”Diane”, “Ladd”));

System.out.println(nomes);

// => [Diane Ladd, Harry Stanton, Laura Dern]

Aprofundando

Procurar e estudar na documentação do java as classes apresentadas nesta aula: (veja java.util.*) em http://java.sun.com/j2se/1.5.0/docs/api

Durante os próximos estudos de java é essencial manter este endereço aberto em uma janela do navegador, de modo a tirar dúvidas a respeito do funcionamento de alguma classe java.

Na Seqüência

  • dia 29 de janeiro: Exceções e outros truques

Dúvidas? vá para o fórum.

Procure os mais baratos Livros sobre a Web, Livros sobre Java, Livros HTML ou Livros CSS nas melhores lojas do Brasil.

Posted on 09:58, dezembro 18th, 2007 by Prof. Luis Eduardo

Sejam bem vindos, esta é a décima aula de Programação Web em Java, para saber mais sobre o curso, começe em Curso de Programação Web em Java - CPWJ.

Hoje iremos aprofundar alguns conceitos de orientação a objeto .

Classes e Interfaces, Conceitos

Vamos começar com uma revisão de alguns conceitos já passados na última aula:

  • Classe: um modelo para um Objeto

  • Interface: uma especificação

  • Instância: um objeto de uma Classe ou Interface fisicamente representado na memória

  • Membros de uma Classe:

    • Método: uma conjunto sequencial de instruções

    • Campo: variável associada com um objeto particular

    • Campo estático: variável compartilada entre todos os objetos de uma classe.

Tipos de Dados

Existem dois tipos de dados em Java, os tipos primitivos e os tipos objetos.

Objetos

Usar a palavra chave “new” para criar um objeto. Este comando irá reservar espaço para um novo objeto na memória, chamar o construtor do objeto e retornar o endereço para o novo objeto.

Modelo de definição de uma Classe:

[acesso] [abstract/final] class NomeDaClasse

[extends NomeClassePai]

[implements NomeDaInterface...] {

//construtores

//métodos membros

//campos membros

}

Exemplo de Sintaxe

public class ContaBancaria {

}

Membros das Classes

Ao escrever uma classe nós podemos definir os seguintes membros:

  • Construtores

  • Métodos e campos

  • Métodos e campos estáticos

  • Classes alinhadas

Vamos detalhar cada um dos membros, começando pelos Construtores.

Construtores

São os métodos chamados automaticamente na criação dos objetos. Deve ter o mesmo nome da classe que a possue. Tem o objetivo de realizar a inicialização de um objeto da classe.

 

Modelo de Construtor

[acesso] NomedaClasse ([argumentos...]) {

//corpo do construtor

}

 

Exemplo de Sintaxe Construtor

public class ContaBancaria {

public ContaBancaria(){ // veja que o nome do construtor é o mesmo da classe

saldo=0;

}

}

 

Exemplo de Sintaxe de Múltiplos Construtores

public class ContaBancaria {

public ContaBancaria(){

saldo=0;

}

public ContaBancaria(int saldoInicial){

saldo=saldoInicial;

}

}

Apesar de possuir o mesmo nome são construtores diferentes, pois possuem parâmetros diferentes.

Métodos

Métodos são usados para realizar funções modificando o estado dos objetos. Podem ter vários parâmetros, e retornar um único valor. Nos casos que não retornam valor deve ser utilizado a parlavra chave void.

Modelo de Método

[acesso] tipoRetorno nomeDoMétodo ([argumentos...]) {

//corpo do método

}

Exemplo de Método

 

public class ContaBancaria {

public int getSaldo(){

return saldo;

}

}

Sobrecarga de métodos

Uma classe pode possuir dois métodos com mesmo nome, desde que os seus argumentos sejam diferentes.

Por exemplo:

int getSaldo() {…}

int getSaldo(String tipo) {…}

Java reconhece qual método deverá executar verificando quantos e que tipos de parâmetros são apresentados na chamada.

Exemplo:

int x=minhaClasse.getSaldo(“total”); //chamará o segundo método.

 

Campos

Um campo é como uma variável e armazena um estado do objeto. É sempre relacionado a um tipo de dado que determina o que ele pode armazenar.

Modelo de Campo

[acesso] tipoDeDado nomeCampo [= valor];

Exemplos de Campos

 

public class ContaBancaria {

public int saldo;

public Date ultimaTransacao;

public List transacoes;

}

Juntando tudo

public class ContaBancaria {

private int saldo; // campo

public ContaBancaria() { //construtor

saldo= 0;

}

public void retirada(int valor) { //método

saldo = saldo – valor;

}

public void deposito (int valor) { //método

saldo = saldo + valor;

}

}

Controle de Acesso

Para controlar o acesso aos dados membros temos 4 tipos de acesso direrentes que determinam que classes tem acesso:

  • public – qualquer outra classe

  • protected - somente subclasses

  • (default) – somente classes no mesmo pacote (package)

  • private – somente acessível por métodos da mesma classe

Estes níveis de acesso são usados para garantir a abstração e encapsulamento dos objetos.

Herança

É o mecanismo que permite uma classe herdar funcionalidades de outra classe, permitindo abstração de dados e procedimentos e diminuindo a complexidade de grandes sistemas de dados.

Usamos herança quando duas idéias tem diferentes comportamentos mas com funcionalidades sobrepostas:

 

ContaBancaria => ContaCorrente

ContaBancaria => ContaPoupanca

 

Interfaces

Uma interface é uma especificação de uma classe. Declara-se métodos, mas não os define. Não tem contrutores. O objetivo é expecificar um padrão de uso (interface) de um conjunto de classes diferentes.

 

Modelo de Interfaces

[acesso] interface NomeDaInterface

[extends ListaDeNomeDeInterface...] {

//declaração de métodos

}

 

Exemplo de Interface

public interface ContaBancaria {

public void retirada (int valor); //nenhum método é definido na interface, somende declarado

public void deposito (int valor);

public int getSaldo ();

}

 

Como utilizar uma Interface?

Uma vez definido uma interface, podemos escrever classes, ou mesmo outras interfaces que implementam (implement) ou extendam (extend) esta interface.

Quando uma classe implementa uma interface, esta classe deve possuir em seu corpo cada um dos métodos declarados desta interface. Se uma classe implementa mais de uma interface, ela deve possuir cada uma dos métodos de cada uma das interfaces que implementa.

 

Exemplo usando a Interface

public class ContaPoupanca implements ContaBancaria {

private int saldo;

public ContaPoupanca (int saldoinicial) {

saldo= saldoinicial;

}

public void somaJuros(int juros){ //função particular de ContaPoupanca

saldo=saldo+(saldo*(juros)/100);

}

 

//implementando métodos da interface ContaBancaria:

public void retirada (int valor) {

saldo= saldo – valor;

}

 

public void deposito (int valor) {

saldo = saldo + valor;

}

public int getSaldo () {

return saldo;

}

}

Classes Abstratas

São uma mistura de interfaces e classes, podendo definir métodos e possuir campos. Porém podem apresentar métodos somente declarados, e não definidos.

A idéia é capturar o estado de uma idéia e também sua funcionalidade.

Exemplo de Classe Abstrata

public abstract class ContaBancaria {

private int saldo; // campo

public void retirada(int valor); //função não definida pela classe abstrata, porque difere de tipo de conta bancária para outra.

public void deposito (int valor) {

saldo = saldo + valor;

}

}

Exemplo extendendo uma Classe Abstrata

public class ContaCorrente extends ContaBancaria {

public ContaCorrente(){

saldo=0;

}

public void retirada(int valor){

if((saldo-valor)<0) {

throw new RuntimeException (“Insuficiencia de fundos”);

} else {

saldo=saldo-valor;

}

}

}

Exemplo de outro tipo de Conta Bancaria:

public class ContaCorrenteEspecial extends ContaBancaria {

private limiteChequeEspecial;

public ContaCorrenteEspecial(){

saldo=0;

limiteChequeEspecial=1000;

}

public void retirada(int valor){

if((saldo-valor)<limiteChequeEspecial) {

throw new RuntimeException (“Estourado Limite Cheque Especial”);

} else {

saldo=saldo-valor;

}

}

}

Polimorfismo

Consiste na capacidade de objetos de tipos diferentes responder a métodos de mesmo nome e tipo. Isso acontece quando usamos herança. A máquina virtual java automaticamente determina qual das funções devem ser executadas.

A classe Object

Quando uma classe não extende nenhuma outra classe, implicitamente ela extende a classe java.lang.Object. Esta é uma classe da biblioteca java que contém um conjunto de métodos que assim ficam disponíveis para qualquer classe que você definir. os principais métodos da classe Object são: clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString e wait.

Sobreposição de métodos (overriding)

Se uma classe A extende uma classe B, então B é a classe pai (superclass) de A. E, a classe A é uma classe filha (subclass) de B. Quando a classe pai possui um método definido, a classe filha pode ter um método com mesmo nome e tipo para modificar o comportamento do método da classe pai. Isso chama-se sobreposição (overriding).

Modificando um método da Superclass

A classe Object possui um método chamado equals que verifica se dois objetos são o mesmo, isto é, se duas variáveis estão apontando para o mesmo objeto. (revisem a última aula se não entenderam)

Porém em alguns tipos de objetos a noção de igualdade dá-se de maneira totalmente distinta. No nosso exemplo de conta bancária, igualdade poderia dizer que duas contas possuem o mesmo saldo. Graças ao polimorfismo e sobreposição é possível mudar o método equals para realizar exatamente esta verificação.

Usando o método equals padrão

ContaCorrente c1 = new ContaCorrente(100);

ContaCorrente c2 = new ContaCorrente(100);

c1.equals(c1); // verdadeiro

c2.equals(c2); // verdadeiro

c1.equals(c2); // falso, como são dois objetos a função equals retorna falso.

 

Modificando nossa função “equals”, usando overriding:

public class ContaCorrente extends ContaBancaria {

public boolean equals (Object aux){

if(aux instanceof ContaCorrente){ //verifica se tipo de dado do parâmetro está correto

ContaCorrente aux2 = (ContaBancaria) aux;

return saldo == aux2.saldo; //retorna true se saldo igual

} else {

return false; //se tipo incorreto não é igual

}

}

 

}

 

Usando nova função “equals”

ContaCorrente c1 = new ContaCorrente(100);

ContaCorrente c2 = new ContaCorrente(100);

c1.equals(c1); // verdadeiro

c2.equals(c2); // verdadeiro

c1.equals(c2); // verdadeiro, pois agora o que se compara é o saldo, não a posição do objeto

 

Usando variáveis do tipo Superclass

Variáveis de um tipo podem armazenar dados de tipos subclasses

Object o1 = new ContaCorrente(100); //Object é superclass de qualquer classe

Object o2 = new ContaCorrente(100);

Object é o tipo em tempo de Compilação (compile-time) e ContaCorrente é o tipo em tempo de execução (runtime).

Chamada de métodos em tempo de execução

Quando chamamos um método por uma variável do tipo superclass mas com um objeto subclass armazenado, o método executado será o do subclass. No nosso exemplo, chamar o método o1.equals(o2), iria chamar a função “equals” definida em ContaCorrente.

Isso acontece porque Java escolhe o método a ser chamado em tempo de execução e não em tempo de compilação.

Exemplo usando ContaCorrente e ContaCorrenteEspecial

ContaBancaria c1 = new ContaCorrente(10);

ContaBancaria c2 = new ContaCorrenteEspecial(10);

c1.retirada(12); //chamará ContaCorrente.retirada(int) e causará uma exceção por insuficiência de saldo

c2.retirada(12); //chamará ContaCorrenteEspecial.retirada(int) e não apresentará problemas.

 

As vantagem de uso de tipos abstratos como demonstrado aqui é que os detalhes de implementação são mais simples de modificar sem mudanças nas classes que usam estes tipos abstratos.

Nas próxima aula iremos lidar com coleções e listas para fixar exatamente estes conceitos. Porém isso vai ser somente em 22 de janeiro, pois estou entrando em férias, e me reservei no direito de aproveitar os 20 primeiros dias do ano sem nenhuma preocupação. Estarei me casando no dia 12 de janeiro, e só vou voltar a este site quando voltar a trabalhar também na faculdade e na Sabesp.

Para quem acompanha os artigos astronômicos, só irei postar se for algo realmente extraordinário. Um abraço e boas férias.

Na Seqüência

  • dia 25 de dezembro: folga é Natal. Entraremos em recesso com o curso, estaremos de volta dia 22 de janeiro, ao final de minhas merecidas férias.
  • dia 22 de janeiro: Coleções, Hashing e Comparadores.

Dúvidas? vá para o fórum.

Procure os mais baratos Livros sobre a Web, Livros sobre Java, Livros HTML ou Livros CSS nas melhores lojas do Brasil.

Buscar:

Arquivos

Índice

Arquivo

agosto 2008
S T Q Q S S D
« jul    
 123
45678910
11121314151617
18192021222324
25262728293031

RSS Meu FriendFeed

Contato