domingo, 11 de novembro de 2012

Jdk 1.8 e projeto lambda

Vamos ao Java 8.

public class TestLambda {

    public interface Acceptor {
        public boolean accept(int num);
    }

    public static void main(String[] args){
        System.out.println("123");
        printNumbers( i -> i % 3 == 0);
    }

    public static void printNumbers(Acceptor acceptor){
        for(int i = 0; i < 10; i++)
            if (acceptor.accept(i))
                System.out.println("Accept " + i );
    }
}

Observe a linha 9.

printNumbers( i -> i % 3 == 0);

É a chamada expressão lambda. A leitura é funcional, na verdade é uma instancia da interface Acceptor sendo criada na hora da compilação. Costumo fazer a leitura desse tipo de código da seguinte forma: Para um i, de tal forma que i dividido por tres seja zero.

Para que esse código funcione será necessário que os parâmetros da expressão lambda sejam aderentes ao único método da interface Acceptor, que criamos para declarar a expectativa da função printNumbers.

O mais interessante desse código está no arquivo .class compilado. Os primeiros testes do projeto Lambda criava uma classe anonima para a expressão da linha nove mas as últimas verões já estão usando a nova instrução invokeDinamic, veja.

Compiled from "TestLambda.java"
public class TestLambda {
  public TestLambda();
    Code:
       0: aload_0       
       1: invokespecial #1                  
       4: return        

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2                  
       3: ldc           #3                  
       5: invokevirtual #4                  
       8: invokedynamic #5,  0              
      13: invokestatic  #6                  
      16: return        

  public static void printNumbers(TestLambda$Acceptor);
    Code:
       0: iconst_0      
       1: istore_1      
       2: iload_1       
       3: bipush        10
       5: if_icmpge     49
       8: aload_0       
       9: iload_1       
      10: invokeinterface #7,  2 
      15: ifeq          43
      18: getstatic     #2            
      21: new           #8                  
      24: dup           
      25: invokespecial #9                  
      28: ldc           #10                  
      30: invokevirtual #11                 
      33: iload_1       
      34: invokevirtual #12                 
      37: invokevirtual #13                 
      40: invokevirtual #4                  
      43: iinc          1, 1
      46: goto          2
      49: return        
}

O código pode parecer que não muda muito, mas agora é possível alguma coisa funcional com java. Quando essa implementação estiver completa será possível fazer ordenação de lista de forma muito fácil, basta passar uma assinatura de método que implemente comparable com o exemplo de código a seguir.

listaDeClientes.sort( cliente -> cliente.getNome() );
// Ou uma passando a própria referencia 
// para o método que retorna um comparable.
listaDeClientes.sort( Cliente::getNome );
De uma olhada na página do JDK8 para baixar o preview ou na página do projeto lambda.

segunda-feira, 2 de julho de 2012

Pascal Estruturado

Encontrei um livro de Pascal Estruturado na casa dos meus pais dos tempos em que eu estava aprendendo a programar. Já estava a algum tempo com vontade de postar uma série de blogs do tipo "Desafio e Solução". Como dou aula de programação é uma oportunidade de testarmos os conhecimentos.

O livro supõe a solução em Pascal, uma linguagem procedural, mas os desafios são bem interessantes. Acredito que a solução pode ter várias "caras", mais orientadas a objeto ou mais procedural, vou tentar apresentar a solução de ambas as formas.

Segue o primeiro:

[ 1 Questão ]

Construir uma tabela de perda de carga em tubulações para vazões que variam de 0,1 a 10 litros/segundos, de 0,1 em 0,1, através da formula de Hanzen Williams dada a seguir:


J = Perda de Carga 
Q = Vazão(metros cúbicos/2)
D = Diâmetro do tubo( metros quadrados)
C = Coeficiente de rugosidade

Os valores de D e C devem ser lidos do teclado, deve terminar as contas quando for informado um D = 0.