sexta-feira, 29 de março de 2013

Usando HashSet em Java


Uma estrutura de dados tipo HashSet é uma implementação como uma tabela hash para um conceito de conjuntos, assim os seus elementos são armazenados em uma posição derivada de seu conteúdo (hash map). Esta classe permite o elemento null.

As estruturas em hash oferecem performance de tempo constante para as operações básicas (add, remove, contains e size), desde que a função hash apresente uma boa distribuição dos elementos.

Vamos ver no vídeo a seguir como utilizar esta importante classe de dados.



terça-feira, 26 de março de 2013

Gerando QrCode em Java

QR Code é um código de barras bidimensional (no formato de um quadro) que pode ser facilmente escaneado principalmente por smartphones (celulares) equipados com câmera. Assim o código pode ser  convertido em diversos tipos de informação como por exemplo:
  • um texto,
  • um endereço URI,
  • um número de telefone,
  • uma localização georreferenciada,
  • um e-mail,
  • um contato (no formato vCard)
  • um SMS, etc.
Vamos fazer uma classe simples com javax.swing que recebe os dados de um campo texto e transforma este conteúdo em um código QR. Para isto estamos utilizando uma API de kenglxn que encapsula bem os recursos para geração do QR Code. Você pode achar os arquivo no site.

Vamos ver a construção da nossa classe:


QR quer dizer "Quick Response".

As bibliotecas necessárias para a criação do código estão aqui.

sábado, 23 de março de 2013

Utilizando Executors

Desde o Java 5 temos uma classe denominada java.util.concurrent.Executors. Esta classe permite gerar e gerenciar de uma forma mais fácil threads, que são o mecanismo básico (juntamente com socket) para nosso programa de chat no servidor.

Vamos ver como isto funciona.


sexta-feira, 22 de março de 2013

Ler o conteudo de um diretório utilizando DirectoryStream

Vamos ver mais uma classe de Java NIO - DirectoryStream.

Na verdade DirectoryStream não é uma classe, mas uma interface, isto quer dizer que ela não pode ser instanciada (não dá para usarmos o operador new) e sua função é de definir os métodos que devem ser implementados por outra classe que a estende (implementa).

No nosso caso, estamos utilizando Files.newDirectoryStream é uma factory que retorna um objeto que implementa esta interface. O Java implementa três versões deste método:
  • newDirectoryStream(Path):
    • abre o diretório especificado e permite varrer todas as suas entradas
    • o único parâmetro é um Path
  • newDirectoryStream(Path, DirectoryStream.Filter<>)
    • equivale ao primeiro caso, porém passamos também um filtro, que restringe a somente as entradas que passarem neste filtro.
  • newDirectoryStream(Path, String)
    • equivale ao segundo caso acima, porém o filtro é passado como uma String que deve possuir um formato do tipo GLOB.
Vamos a nossa classe:

terça-feira, 19 de março de 2013

Recursividade - Parte 2 ou MergeSort

O merge sort é um algoritmo de ordenação que utiliza recursividade em uma estratégia do tipo dividir-para-conquistar que consiste em
  • Dividir: o conjunto de dados em vários subconjuntos e ordenar esses subconjuntos através da recursividade, isto é, por divisão sucessiva até que o problema fique simples (veja no vídeo)
  • Conquistar: após todos os subconjuntos terem sido ordenados ocorre a união das resoluções em um subconjunto maior até que tenhamos todos o conjunto original ordenado.
No vídeo fica claro que a execução é feita em 3 passos:
  1. Dividir os dados em subconjuntos pequenos;
  2. Classificar as duas metades recursivamente aplicando o merge sort;
  3. Juntar as duas metades em um único conjunto já ordenado.



Como este algoritmo do Merge Sort usa a recursividade em alguns problemas esta técnica não é muito eficiente devido ao alto consumo de memória e tempo de execução. As principais recomendações para tornar este algoritmo mais eficiente são:
  • como o merge sort não é muito eficiente para pequenos conjuntos, devemos utilizar um outro método para subconjuntos com 10 ou menos elementos
  • verificar se o conjunto de dados já está ordenado
  • reduzir o tempo de ordenação eliminando a necessidade de cópia para a estrutura de dados auxiliar.
Vamos ver a nossa classe:


Você vai encontrar diversas informações úteis sobre este algoritmo no site do prof Sedgewick.

segunda-feira, 18 de março de 2013

Recursividade - Parte 1

Neste post vamos entender um pouco sobre recursividade. Para isto eu fiz um vídeo que faz uma rápida apresentação do assunto e mostra como esta técnica pode ser empregada para resolver três diferentes problemas de computação:
  • Como calcular o fatorial de um número inteiro positivo;
  • Como resolver o problema do quebra cabeças denominado Torre de Hanói; e
  • Como gerar uma sequência de Fibonacci.
Vamos ao vídeo

Vamos calcular o fatorial

Vamos calcular a sequência de Fibonacci


Vamos resolver o problema da Torre de Hanói


Veja como construi esta classe. Coloquei no final os atributos e o método estático main() está no início da classe. Normalmente não utilizo este formato, mas ele ajuda a destacar a entrada da operação da classe.

No próximo post abre este assunto vamos ver um algoritmo de ordenação de dados que utiliza recursividade e também por ser muito eficiente é utilizado como algoritmo padrão em diversas linguagens inclusive o Java - estou falando do mergesort.

sábado, 16 de março de 2013

Fazendo um chat em java - Parte 2

Vamos ver agora como ficou nossa classe. O funcionamento básico do programa pode ser descrito como:

  • Em main(), criamos uma instância de java.net.ServerSocket utilizando o socket localhost:61666. A porta 61666 pode ser alterada via argumento na linha de comando. Este socket permite que os clientes possam tentar conectar com o servidor.
  • colocamos um loop contínuo (sem saída) onde
    • verificamos se existe uma requisição de conexão verificando ServerSocket.accept(), quando existe este método retorna um socket denominado conexao
    • criamos uma thread que recebe o socket conexao como parâmetro de passagem
    • dentro da thread (método run()) criamos duas instâncias
      • entrada: que permite receber as mensagens enviadas pelo cliente
      • saida: que permite enviar mensagens para o cliente
    • esperamos que a primeira mensagem contenha o nome do usuário usando
      • usuario = entrada.readLine()
    • comparamos este nome enviado com os nomes guardados na lista clientesLogados
      • se existir, manda mensagem de erro
      • se não existir, coloca o nome na lista clientesLogados e entra em loop até receber uma mensagem /sair


No próximo post veremos um exemplo de uma classe cliente usando Socket.

sexta-feira, 15 de março de 2013

Fazendo um chat em java - parte 1


Para podermos nos comunicar vamos ter que criar primeiro a nossa classe servidora do chat. Ela irá rodar no nosso servidor principal, receberá as conexões dos clientes e fará a comunicação entre eles. Para entender melhor o funcionamento deste servidor, precisamos conhecer o que é um socket e um servidor.

A definição de socket é um ponto de conexão em um link de comunicação de mão dupla entre dois programas rodando na rede, este socket é caracterizada pelo endereço IP e a porta que a aplicação verifica. Toda conexão TCP é identificada unicamente por estes dois parâmetros. Vamos ver como esta comunicação funciona:

a) O servidor fica rodando e escutando o socket (porta) esperando por uma requisição de conexão de um cliente. (isto equivalente a dizer que ele fica em um loop sem fim como veremos no programa)

b) Já o cliente, deve conhecer o socket que irá conectar (endereço e porta do servidor). Para conectar o cliente realiza uma comunicação com o servidor na porta determinada, devendo se identificar para o servidor.

c) O servidor ao receber e autorizar a conexão, armazena a porta e endereço de onde vem a comunicação do cliente e mapeia este socket do cliente com o canal de comunicação. No nosso exemplo, usamos o nome do usuário que é enviando na mensagem de requisição para mapear com o scocket do cliente - criamos um hashmap com estas duas informações

d) Tendo o servidor aceitado a conexão, ele cria um novo socket para realizar a comunicação. Através deste socket o servidor consegue falar com o cliente.

e) Já no lado do cliente, se a conexão é aceita, o socket (do cliente) é criado com sucesso. O cliente pode agora utilizar este socket para comunicar com o servidor.

OBS: O servidor continuar continua esperando novas conexões pelo socket do servidor.

A comunicação é feita mediante a leitura ou escrita no socket. O vídeo abaixo representa este processo




Manipulando elementos gráficos em um applet

Um applet é um programa em Java que roda em um navegador com algumas características especiais - primeiro é um programa Java completo e segundo possui diversas restrições de acesso. Um applet roda em uma área de memória especial denominada sandbox que limita o acesso do programa à máquina física do usuário.

Para criar um applet temos que extender a classe java.applet.Applet. Um applet não chama o método main() e por isto ele não precisa ser definido. Por padrão, os applets são projetados para rodarem dentro de páginas web. Para colocar um applet em uma página web utilizamos a tag applet com uma sintaxe equivalente a abaixo:

<applet code="BouncingLinesApplet.class" width="400" height="400">
Nosso exemplo de Java applet
</applet>

Quando a página é carregada, também a classe java do applet é baixada. Estando a JVM instalada no computador, o applet pode ser visualizado dentro da página. Em aplicações mais complexas, podemos empacotar todas as classe em um arquivo JAR.

Durante a execução de um applet vamos notar que 5 métodos são chamados:
  • init: Este método é utilizado para inicialização e é chamado logo depois que os parâmetros na tag applet (do html) são processados.
  • start: Este método é chamado logo depois de init() e também quando o usuário retorna a página que contém o applet depois que navegou em outras.
  • stop: É chamado quando o usuário sai da página que contém o applet, mas pode ser chamado também internamente pelo applet. A implementação default não faz nada.
  • destroy: É chamado quando o navegador é fechado.
  • paint: É chamado logo depois de start() e sempre que for solicitado repaint().

Veja como ficou nossa classe:


terça-feira, 12 de março de 2013

Fazendo um chat em java

Vamos ver como fazer um chat simples em Java utilizando socket. Existem métodos mais eficiente e também mais fáceis de realizar esta tarefa utilizando frameworks existentes no mercado.

Testei recentemente um framework denominado ActiveMQ da Apache que nos fornece todos os recursos para criamos produtores e consumidores de mensagem que funciona via Swing, web etc. A Apache nos fornece inclusive um exemplo de demonstração funcional que podemos utilizar facilmente para criar um chat que nos atenda. A interface do software de demonstração está mostrado na figura abaixo:


No nosso caso, como ainda estamos aprendendo vamos fazer dois exemplos:

1) no próximo post, vamos ver como construir uma classe que permita gerar um chat via socket. Sendo o cliente com a interface simples mostrada abaixo

2) depois veremos a mesma funcionalidade utilizando características do JMS (como no ActiveMQ).

Então até o próximo post....

sexta-feira, 8 de março de 2013

Trabalhando com ordenação - Parte 2

Neste vou alterar o programa que vimos na parte 1 para ele fique um pouco mais profissional permitindo receber parâmetros pela linha de comando. Para que isto funcione irei utilizar algumas classes do Apache Commons da API CLI. Esta API permite que consigamos identificar e interpretar as opções passadas pela linha de comando para o programa.

Vamos utilizar diversas classes que comporão a solução de acesso aos parâmetros, são elas:
  • Options
    • representa uma Collection de objetos do tipo Option
  • Option
    •  representa uma única opção de linha de comando, mantendo informações como:
      • nome,
      • letra que representa a opção,
      • descrição do comando,
      • se possui argumentos adicionais ou não,
      • se é obrigatório ou não
      • etc
  • OptionBuilder
    • é um construtor que permite criar uma Option de uma maneira mais fácil
  • CommandLine
    • representa a lista deargumentos que foi passada como parâmetro para o programa interpretada frente Options
  • BasicParser
    •  interpretador básico de argumentos
  • HelpFormatter
    • formata automaticamente um help baseado nos argumentos de comando contido em Options
Vamos ao vídeo da construção:


Nossa classe é:
 











quinta-feira, 7 de março de 2013

Trabalhando com ordenação - Parte 1

Vamos a nossa primeira parte da classe de ordenação.

Existe uma simulação que mostra bem o funcionamento da ordenação passo a passo. Clique aqui para ver. O vídeo da simulação pode ser visto abaixo. Acredito que esta simultação permite ver com maior clareza o trabalho que é executado pelo método de ordenação.


A criação da nossa classe pode ser vista no seguinte vídeo:


A classe final é:

quarta-feira, 6 de março de 2013

Trabalhando com ordenação - Parte 0

O Java já traz diversos métodos de ordenação para classes como Array, ArrayList, List etc. Vamos dar uma olhada neles daqui a alguns posts. Neste primeiro post vou mostrar como fazer um aplicativo utilizando um algoritmo de ordenação bastante utilizando na literatura. Por quê ele é bastante visto? Não é porque que ele é bom, na prática não vamos utilizá-lo. As classes do Java utilizam algoritmos baseados em quicksort ou mergesort que são muito mais eficientes. Então por quê? É só porque ele é bem fácil de entender e portanto para quem está aprendendo o conceito do que está sendo feito abre caminho para algoritmos mais complexos e mais rápidos.

Vou dividir este assunto em 3 partes:

  • primeiro vou fazer um programa com o algoritmo funcionando para vocês verem como funciona um método de ordenação
  • depois vou alterar o programa para ele ficar um pouco mais profissional permitindo receber parâmetros pela linha de comando que alteram o comportamento do programa como mostrado na figura abaixo
  • por último vou mostrar como tornar mesmo algoritmo de ordenação capaz de trabalhar com diversos tipos de dados como String, Integer etc.

segunda-feira, 4 de março de 2013

Calculando o valor hash de um arquivo

Em um post anterior calculamos o CRC de um arquivo. Como disse antes o CRC não é um método para garantir a segurança da mensagem (no caso do arquivo). Neste post vamos ver como criar um hash para um arquivo.

Uma função hash é basicamente um algoritmo que recebe um bloco de dados (no nosso caso um array de bytes que contem o conteúdo do arquivo) e retorna uma seqüência de bits de tamanho fixo de tal forma que qualquer alteração dos dados irá alterar o valor de hash.

Os dados a serem codificados são muitas vezes chamado de "mensagem" daí a razão de encontrarmos em Java como uma classe MessageDigest. O resultado da função hash é chamado valor hash, message digest ou digest. É por esta razão que a geração do hash em Java termina com a chamada do método digest().


A função hash ideal tem quatro propriedades principais:

  • é fácil de calcular o valor de hash para qualquer mensagem
  • é impossível gerar uma mensagem que tem um hash dado (não dá para transformar o hash na mensagem original)
  • é inviável para modificar uma mensagem sem alterar o hash
  • é praticamente impossível encontrar duas mensagens diferentes com o mesmo hash (isto é chamado de collision resistance)


Com estas pré-condições podemos ver que um hash autentica uma mensagem e é por isto que queremos saber como utilizar este tipo de "coisa".

Temos diversos algoritmos para calculo de hash. Neste post vamos ver como gerar dois dos mais usados.:

  • MD5 - você pode ler mais na RFC 1321 que define o Message-Digest algorithm  e
  • SHA que vem de "secure hash algorithm". Existem variações de SHA, denominadas SHA-0, SHA-1 e SHA-2. Mais comumente iremos encontrar SHA-1 (que gera digests de 160 bits) e SHA-2 com 224, 256, 384 e 512 bits. Hoje em função da capacidade computacional dos equipamentos atuais é recomendável utilizar no mínimo 256 bits. Já existe SHA-3 porém é relativamente novo e não vamos ver como gerá-lo aqui. Para quem quer conhecer mais recomendo a leitura das RFC 3174 que descreve SHA-1 e RFC 6234 que descreve SHA-2.

A teoria é bastante complicada e não vamos entrar nela aqui. Um bom livro é Applied Cryptography, Second Edition: Protocols, Algorthms, and Source Code in C de Bruce Schneier.

Vamos ao nosso código. Para gerar um hash em Java é bastante simples. Precisamos somente da classe java.security.MessageDigest e podemos gerar um hash com três passos:
  1. obtemos um objeto chamando MessageDigest.getInstance(nome do algoritmo que queremos)
  2. chamamos o método update(byte[])
  3. chamamos o método digest() que retorna o hash como um array de bytes
Como queremos ter o hash em um formato apresentável, acrescentei na nossa classe um método converteByteArrayToString que recebe o array de bytes e retorna uma String com a sequência em hexadecimal do valor hash.

Vamos rodar nosso exemplo:

Foi gerado o valor hash com SHA-256. Para calcular SHA-512 basta trocar o nome do algoritmo:

Para MD5 é igual:

Ok. Ficamos assim por hoje....

domingo, 3 de março de 2013

Criando um gráfico em JavaFX - Parte I

Frequentemente no ambiente empresarial precisamos de criar gráficos para representar algum valor de forma mais intuitiva. A criação de gráficos em JavaFX é relativamente simples.

Vamos ver um exemplo utilizando bubble chart. Este é um gráfico bidimensional que desenho bolhas em posições (X,Y) do gráfico, sendo o tamanho da bolha dado por um terceiro parâmetro (o raio da bolha).

A criação está apresentada na figura abaixo. Os passos para criar um gráfico deste tipo são:

  1. criar os eixos X e Y, instanciando a classe NumberAxis
  2. criar a classe BubbleChart, passando os eixos X e Y
  3. criar uma série de dados do tipo Series
    1. cada elemento desta série de dados é representado por um objeto XYChart.Data

Vamos o nosso exemplo rodando:

Vamos rodar a classe para ver o resultado:


 O gráfico foi gerado a partir do arquivo abaixo, que tem o seguinte formato:

  1. primeira linha - tipo String - contendo o nome da série que será apresentada no gráfico
  2. segunda linha - tipo int - contém o número de pontos do gráfico (nossa classe não trata o caso deste número ser maior que a quantidade de pontos existente no arquivo)
  3. da terceira linha em diante - 3 tipos double separados por espaço


O mesmo programa pode ser alterado para mostrar diversas séries. Alteramos linha que contem a leitura do arquivo de dados para permitir ler 3 arquivos, simplesmente acrescentando as duas linhas como a seguir:

dados.addAll(getChartData("dados1.txt"));
dados.addAll(getChartData("dados2.txt"));
dados.addAll(getChartData("dados3.txt"));


O resultado é algo semelhante a imagem abaixo:

Calculando CRC-32

Vocês já tiveram que calcular o CRC alguma vez? Eu precisei implementar poucas vezes. É digo que é bem chato de fazer a conta na mão e só um pouco melhor de implementar um algoritmo eficiente. Mas o Java já fornece isto para nós, o mais difícil é perceber que a classe está em java.util.zip!!

Dêem uma olhada na documentação no site.

Para quem ainda não sabe o que é CRC - ele é uma sigla que vem do inglês Cyclic redundancy check (quer dizer: verificação de redundância cíclica). É uma espécie de código detector de erros, que gera um valor expresso em poucos bits em função de um bloco maior de dados (que é o que queremos verificar, no nosso caso um arquivo). Com isto se transmitimos um arquivo para alguém e mandamos junto o CRC, o destinatário pode detectar erros de transmissão ou armazenamento comparando o valor que ele calcula no arquivo recebido com o CRC que também recebeu.

Notem que isto não garante qualquer integridade da mensagem. Não estamos falando de segurança de dados. Um atacante pode facilmente forjar uma mensagem, gerar um CRC e mandar para você. A única coisa que você consegue é saber se os bytes foram recebidos ok.

Se você quiser saber mais sobre o CRC dê uma olhada neste link da wikipedia (é o texto em inglês, o em português é muito pobre). Você pode ainda dar uma olhada na RFC 1952.

Vamos a nossa classe. O processo em Java é bastante simples e consiste de três etapas:

  1. criamos a classe
  2. chamamos uma (ou diversas vezes) o método update()
  3. chamamos getValue() para obter o CRC

Abaixo a nossa classe comentada:

Queria destacar aqui um método que ainda não utilizei neste blog. É Files.readAllBytes() - ele permite ler todos os bytes de um arquivo na forma de um array. Com isto economizo a chamada para java.io.FileInputStreamjava.io.BufferedInputStream.

Vamos rodar sobre os nossos arquivos:

PS: para aqueles curiosos, estou usando um ambiente muito light feito em Java chamado DrJava toda vez que desenvolvo uma classe pequena e simples. É um único arquivo jar que deixo no meu Skydrive, assim quando vou escrever algo para este blog, basta acessá-lo, rodar e pronto... funciona no linux (estou agora nesta plataforma), em windows e mac.