Neste artigo veremos como construir uma aplicação que realizar o embaralhamento de valores em Java, onde trabalharemos com uma aplicação prática que realizará tal função. Além disso, aproveitamos para adicionar uma outra funcionalidade afim de ordenar os valores, ou seja, além de embaralhar o usuário também poderá ordenar os valores.

O princípio da nossa aplicação funciona com a seguinte lógica: O usuário passará uma lista de valores separados por virgula e executará a função de ordenar ou embaralhar.

Nota: Visando facilitar os clientes da DevMedia, foi desenvolvido um checklist bem legal de Java, não deixe de conferir essa novidade da DevMedia.

Criando a interface gráfica

Como dissemos anteriormente, vamos criar uma aplicação do zero que fará o embaralhamento e ordenamento dos valores passados. Vamos ver a estrutura física do nosso formulário sem nenhuma lógica de negócio e depois adicionar a lógica nos métodos de embaralhar() e ordenar(), conforme mostra a Figura 1.

Fembaralhamento
Figura 1. Fembaralhamento

A janela mostrada acima possui um campo de texto onde serão colocados os valores que devem ser embaralhados ou ordenados, dois botões cada um com sua funcionalidade descrita no próprio label do botão e uma área de texto onde será colocado os resultados obtidos da função escolhida. Nossa janela acima foi construído usando o Netbeans, então colocaremos na Listagem 1 o arquivo Fembaralhamento.form caso você deseje reproduzir a mesma tela no Netbeans.


<?xml version="1.0" encoding="UTF-8" ?>
 
<Form version="1.3" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
  <Properties>
    <Property name="defaultCloseOperation" type="int" value="3"/>
  </Properties>
  <SyntheticProperties>
    <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
  </SyntheticProperties>
  <AuxValues>
    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
  </AuxValues>
 
  <Layout>
    <DimensionLayout dim="0">
      <Group type="103" groupAlignment="0" attributes="0">
          <Group type="102" attributes="0">
              <EmptySpace max="-2" attributes="0"/>
              <Group type="103" groupAlignment="0" attributes="0">
                  <Group type="103" groupAlignment="0" max="-2" attributes="0">
                      <Component id="jTextAreaResultado" alignment="0" pref="365" 
                      max="32767" attributes="1"/>
                      <Group type="102" attributes="0">
                          <Component id="jButtonEmbaralhar" min="-2" max="-2" attributes="0"/>
                          <EmptySpace min="-2" pref="17" max="-2" attributes="0"/>
                          <Component id="jButtonOrdenar" min="-2" max="-2" attributes="0"/>
                      </Group>
                      <Component id="jLabel4" min="-2" max="-2" attributes="0"/>
                      <Component id="jTextFieldNumeros" alignment="0" max="32767" attributes="1"/>
                  </Group>
                  <Component id="jLabel5" alignment="0" min="-2" max="-2" attributes="0"/>
              </Group>
              <EmptySpace pref="23" max="32767" attributes="0"/>
          </Group>
      </Group>
    </DimensionLayout>
    <DimensionLayout dim="1">
      <Group type="103" groupAlignment="0" attributes="0">
          <Group type="102" alignment="0" attributes="0">
              <EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
              <Component id="jLabel5" min="-2" max="-2" attributes="0"/>
              <EmptySpace max="-2" attributes="0"/>
              <Component id="jTextFieldNumeros" min="-2" max="-2" attributes="0"/>
              <EmptySpace min="-2" pref="27" max="-2" attributes="0"/>
              <Group type="103" groupAlignment="3" attributes="0">
                  <Component id="jButtonEmbaralhar" alignment="3" min="-2" max="-2" 
                  attributes="0"/>
                  <Component id="jButtonOrdenar" alignment="3" min="-2" max="-2" attributes="0"/>
              </Group>
              <EmptySpace min="-2" pref="24" max="-2" attributes="0"/>
              <Component id="jLabel4" min="-2" max="-2" attributes="0"/>
              <EmptySpace max="-2" attributes="0"/>
              <Component id="jTextAreaResultado" min="-2" pref="122" max="-2" attributes="0"/>
              <EmptySpace pref="22" max="32767" attributes="0"/>
          </Group>
      </Group>
    </DimensionLayout>
  </Layout>
  <SubComponents>
    <Component class="javax.swing.JButton" name="jButtonEmbaralhar">
      <Properties>
        <Property name="text" type="java.lang.String" value="Embaralhar"/>
      </Properties>
    </Component>
    <Component class="javax.swing.JButton" name="jButtonOrdenar">
      <Properties>
        <Property name="text" type="java.lang.String" value="Ordenar"/>
      </Properties>
    </Component>
    <Component class="javax.swing.JTextArea" name="jTextAreaResultado">
      <Properties>
        <Property name="columns" type="int" value="20"/>
        <Property name="lineWrap" type="boolean" value="true"/>
        <Property name="rows" type="int" value="5"/>
      </Properties>
    </Component>
    <Component class="javax.swing.JLabel" name="jLabel4">
      <Properties>
        <Property name="text" type="java.lang.String" value="Resultado:"/>
      </Properties>
    </Component>
    <Component class="javax.swing.JTextField" name="jTextFieldNumeros">
      <Properties>
        <Property name="text" type="java.lang.String" value="1,2,3"/>
      </Properties>
    </Component>
    <Component class="javax.swing.JLabel" name="jLabel5">
      <Properties>
        <Property name="text" type="java.lang.String" value="Valores: (Separados por virgula)"/>
      </Properties>
    </Component>
  </SubComponents>
</Form>
Listagem 1. Fembaralhamento.form

Para codificação dos métodos (ainda sem nenhum conteúdo) nós usamos a IDE Eclipse, conforme a Listagem 2, mas fique a vontade para continuar usando o Netbeans se preferir.


package br.com.dev.gui;
 
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
 
public class FEmbaralhamento extends javax.swing.JFrame {
    
    /** Creates new form FEmbaralhamento */
    public FEmbaralhamento() {
        initComponents();
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Código Gerado "
    >//GEN-BEGIN:initComponents
    private void initComponents() {
        jButtonEmbaralhar = new javax.swing.JButton();
        jButtonOrdenar = new javax.swing.JButton();
        jTextAreaResultado = new javax.swing.JTextArea();
        jLabel4 = new javax.swing.JLabel();
        jTextFieldNumeros = new javax.swing.JTextField();
        jLabel5 = new javax.swing.JLabel();
 
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        jButtonEmbaralhar.setText("Embaralhar");
        
        jButtonEmbaralhar.addActionListener(new ActionListener() {
                    
                    @Override
                    public void actionPerformed(ActionEvent e) {
                           embaralhar();                     
                    }
             });
 
        jButtonOrdenar.setText("Ordenar");
        
        jButtonOrdenar.addActionListener(new ActionListener() {
                    
                    @Override
                    public void actionPerformed(ActionEvent e) {
                          ordenar();
                           
                    }
             });
 
        jTextAreaResultado.setColumns(20);
        jTextAreaResultado.setLineWrap(true);
        jTextAreaResultado.setRows(5);
 
        jLabel4.setText("Resultado:");
 
        jTextFieldNumeros.setText("1,2,3");
 
        jLabel5.setText("Valores: (Separados por virgula)");
 
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment
                    .LEADING, false)
                        .addComponent(jTextAreaResultado, javax.swing.GroupLayout.DEFAULT_SIZE, 
                        365, Short.MAX_VALUE)
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jButtonEmbaralhar)
                            .addGap(17, 17, 17)
                            .addComponent(jButtonOrdenar))
                        .addComponent(jLabel4)
                        .addComponent(jTextFieldNumeros))
                    .addComponent(jLabel5))
                .addContainerGap(23, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(19, 19, 19)
                .addComponent(jLabel5)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTextFieldNumeros, javax.swing.GroupLayout.PREFERRED_SIZE, 
                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(27, 27, 27)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButtonEmbaralhar)
                    .addComponent(jButtonOrdenar))
                .addGap(24, 24, 24)
                .addComponent(jLabel4)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTextAreaResultado, javax.swing.GroupLayout.PREFERRED_SIZE, 122, 
                javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(22, Short.MAX_VALUE))
        );
        pack();
    }// </editor-fold>//GEN-END:initComponents
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new FEmbaralhamento().setVisible(true);
            }
        });
    }
    
    public void embaralhar(){
     
    }
    
    public void ordenar(){      
       
    }
    
    // Declaração de variáveis - não modifique//GEN-BEGIN:variables
    private javax.swing.JButton jButtonEmbaralhar;
    private javax.swing.JButton jButtonOrdenar;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JTextArea jTextAreaResultado;
    private javax.swing.JTextField jTextFieldNumeros;
    // Fim da declaração de variáveis//GEN-END:variables
    
}
Listagem 2. Fembaralhamento.java

Construindo a lógica dos método embaralhar() e ordenar()

Agora que temos o nosso formulário pronto e os botões chamando os métodos de embaralhar() e ordenar(), como mostrado na Listagem 2, nós podemos dar enfoque maior da construção da lógica destes dois métodos que são o objetivo principal deste artigo, como mostra a Listagem 3.


/**
* Método responsável por embaralhar os valores inseridos no componentes
* jTextFieldNumeros
* */
public void embaralhar() {
     // Limpamos o textArea para garantir que não haja valores
     jTextAreaResultado.setText("");

     // Criamos um array de Strings dividindo os valores separados por virgula
     // através do split()
     String[] numerosAsString = jTextFieldNumeros.getText().split(",");

     // Como não sabemos se há espaço entre os valores, precisamos garantir
     // que eles serão
     // convertidos para um valor inteiro
     List<Integer> numerosAsInteger = new ArrayList<Integer>();
     for (int i = 0; i < numerosAsString.length; i++) {
            // Adicionamos o valore em String para a lista de inteiros,
            // garantindo a remoção dos espaços
            numerosAsInteger.add(Integer.parseInt(numerosAsString[i].trim()));
     }

     // Usamos o shuffle para embaralhar os valores
     Collections.shuffle(numerosAsInteger);

     // Colocamos os valores embaralhados dentro do jTextArea
     for (int i = 0; i < numerosAsInteger.size(); i++) {

            if (numerosAsInteger.size() == i + 1) {
                   jTextAreaResultado.append(numerosAsInteger.get(i).toString());
            } else {
                   jTextAreaResultado.append(numerosAsInteger.get(i).toString()
                                + ",");
            }
     }
}
Listagem 3. Implementação do método embaralhar()

A implementação acima está totalmente comentada para garantir o bom entendimento da lógica deste método. O método primordial é o Collections.shuffle() que realiza o embaralhamento dos valores.

Bom, agora veremos como realizar a ordenação dos valores. Na ordenação podemos usar diversos algoritmos: Quick Sort, Merge Sort, Selection Sort e etc. Não vamos nos ater a explicar quais as vantagens e desvantagens de cada um, o artigo ficaria muito extenso e perderíamos o foco que é o embaralhamento e não ordenação. Enfim, iremos usar um algoritmo simples de ordenação conhecido como Insertion Sort, ele não é o melhor de todos mas é um dos mais simples. Observe a Listagem 4.


/**
* Usando algoritmo de insertion sort para ordenar valores em Java
* */
public void ordenar() {

 // Limpamos o textArea para garantir que não haja valores
 jTextAreaResultado.setText("");

 // Criamos um array de Strings dividindo os valores separados por virgula
 // através do split()
 String[] numerosAsString = jTextFieldNumeros.getText().split(",");

 // Como não sabemos se há espaço entre os valores, precisamos garantir
 // que eles serão
 // convertidos para um valor inteiro
 Integer[] numerosAsInteger = new Integer[numerosAsString.length];
 for (int i = 0; i < numerosAsString.length; i++) {
        // Adicionamos o valore em String para a lista de inteiros,
        // garantindo a remoção dos espaços
        numerosAsInteger[i] = Integer.parseInt(numerosAsString[i].trim());
 }

 for (int i = 1; i < numerosAsInteger.length; i++) {
        for (int var = i; var >= 1
                      && numerosAsInteger[var] < numerosAsInteger[var - 1]; var--) {
               // Troca os elementos
               numerosAsInteger[var] += numerosAsInteger[var - 1];
               numerosAsInteger[var - 1] = numerosAsInteger[var]
                            - numerosAsInteger[var - 1];
               numerosAsInteger[var] -= numerosAsInteger[var - 1];
        }
 }

 // Colocamos os valores embaralhados dentro do jTextArea
 for (int i = 0; i < numerosAsInteger.length; i++) {

        if (numerosAsInteger.length == i + 1) {
               jTextAreaResultado.append(numerosAsInteger[i].toString());
        } else {
               jTextAreaResultado.append(numerosAsInteger[i].toString() + ",");
        }
 }

}
Listagem 4. Implementando o método ordenar()

Este último método, apresentando na Listagem 4, apresenta a lógica de ordenação de valores usando o algoritmo de Insertion Sort, que possui complexidade O(n) para o melhor caso e O(n²) para o pior caso, ou seja, isso nos diz que ele é ótimo para um pequeno número de elementos mas se você pensa em trabalhar com milhares de valores então seria bom começar a pensar em algoritmos mais eficientes e complexos como o Heap Sort.

Finalizando o Fembalhar

Para finalizar este artigo, na Listagem 5 temos a construção da classe Fembalhar completa com todos os métodos implementados e funcionando.


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class FEmbaralhamento extends javax.swing.JFrame {
  
  /** Creates new form FEmbaralhamento */
  public FEmbaralhamento() {
      initComponents();
  }
  
  /** This method is called from within the constructor to
   * initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is
   * always regenerated by the Form Editor.
   */
  // <editor-fold defaultstate="collapsed" desc=" Código Gerado ">//GEN-BEGIN:initComponents
  private void initComponents() {
      jButtonEmbaralhar = new javax.swing.JButton();
      jButtonOrdenar = new javax.swing.JButton();
      jTextAreaResultado = new javax.swing.JTextArea();
      jLabel4 = new javax.swing.JLabel();
      jTextFieldNumeros = new javax.swing.JTextField();
      jLabel5 = new javax.swing.JLabel();

      setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
      jButtonEmbaralhar.setText("Embaralhar");
      
      jButtonEmbaralhar.addActionListener(new ActionListener() {
                  
                  @Override
                  public void actionPerformed(ActionEvent e) {
                         embaralhar();                     
                  }
           });

      jButtonOrdenar.setText("Ordenar");
      
      jButtonOrdenar.addActionListener(new ActionListener() {
                  
                  @Override
                  public void actionPerformed(ActionEvent e) {
                         ordenar();
                         
                  }
           });

      jTextAreaResultado.setColumns(20);
      jTextAreaResultado.setLineWrap(true);
      jTextAreaResultado.setRows(5);

      jLabel4.setText("Resultado:");

      jTextFieldNumeros.setText("1,2,3");

      jLabel5.setText("Valores: (Separados por virgula)");

      javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
      getContentPane().setLayout(layout);
      layout.setHorizontalGroup(
          layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(layout.createSequentialGroup()
              .addContainerGap()
              .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                      .addComponent(jTextAreaResultado, javax.swing.GroupLayout.DEFAULT_SIZE, 365, 
                      Short.MAX_VALUE)
                      .addGroup(layout.createSequentialGroup()
                          .addComponent(jButtonEmbaralhar)
                          .addGap(17, 17, 17)
                          .addComponent(jButtonOrdenar))
                      .addComponent(jLabel4)
                      .addComponent(jTextFieldNumeros))
                  .addComponent(jLabel5))
              .addContainerGap(23, Short.MAX_VALUE))
      );
      layout.setVerticalGroup(
          layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(layout.createSequentialGroup()
              .addGap(19, 19, 19)
              .addComponent(jLabel5)
              .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
              .addComponent(jTextFieldNumeros, javax.swing.GroupLayout.PREFERRED_SIZE, 
              javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
              .addGap(27, 27, 27)
              .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                  .addComponent(jButtonEmbaralhar)
                  .addComponent(jButtonOrdenar))
              .addGap(24, 24, 24)
              .addComponent(jLabel4)
              .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
              .addComponent(jTextAreaResultado, javax.swing.GroupLayout.PREFERRED_SIZE, 122, 
              javax.swing.GroupLayout.PREFERRED_SIZE)
              .addContainerGap(22, Short.MAX_VALUE))
      );
      pack();
  }// </editor-fold>//GEN-END:initComponents
  
  /**
   * @param args the command line arguments
   */
  public static void main(String args[]) {
      java.awt.EventQueue.invokeLater(new Runnable() {
          public void run() {
              new FEmbaralhamento().setVisible(true);
          }
      });
  }
  
     /**
      * Método responsável por embaralhar os valores inseridos no componentes
      * jTextFieldNumeros
      * */
     public void embaralhar() {
           // Limpamos o textArea para garantir que não haja valores
           jTextAreaResultado.setText("");

           // Criamos um array de Strings dividindo os valores separados por virgula
           // através do split()
           String[] numerosAsString = jTextFieldNumeros.getText().split(",");

           // Como não sabemos se há espaço entre os valores, precisamos garantir
           // que eles serão
           // convertidos para um valor inteiro
           List<Integer> numerosAsInteger = new ArrayList<Integer>();
           for (int i = 0; i < numerosAsString.length; i++) {
                  // Adicionamos o valore em String para a lista de inteiros,
                  // garantindo a remoção dos espaços
                  numerosAsInteger.add(Integer.parseInt(numerosAsString[i].trim()));
           }

           // Usamos o shuffle para embaralhar os valores
           Collections.shuffle(numerosAsInteger);

           // Colocamos os valores embaralhados dentro do jTextArea
           for (int i = 0; i < numerosAsInteger.size(); i++) {

                  if (numerosAsInteger.size() == i + 1) {
                         jTextAreaResultado.append(numerosAsInteger.get(i).toString());
                  } else {
                         jTextAreaResultado.append(numerosAsInteger.get(i).toString()
                                      + ",");
                  }
           }
     }
  
     /**
      * Usando algoritmo de insertion sort para ordenar valores em Java
      * */
     public void ordenar() {

           // Limpamos o textArea para garantir que não haja valores
           jTextAreaResultado.setText("");

           // Criamos um array de Strings dividindo os valores separados por virgula
           // através do split()
           String[] numerosAsString = jTextFieldNumeros.getText().split(",");

           // Como não sabemos se há espaço entre os valores, precisamos garantir
           // que eles serão
           // convertidos para um valor inteiro
           Integer[] numerosAsInteger = new Integer[numerosAsString.length];
           for (int i = 0; i < numerosAsString.length; i++) {
                  // Adicionamos o valore em String para a lista de inteiros,
                  // garantindo a remoção dos espaços
                  numerosAsInteger[i] = Integer.parseInt(numerosAsString[i].trim());
           }

           for (int i = 1; i < numerosAsInteger.length; i++) {
                  for (int var = i; var >= 1
                                && numerosAsInteger[var] < 
                                numerosAsInteger[var - 1]; var--) {
                         // Troca os elementos
                         numerosAsInteger[var] += numerosAsInteger[var - 1];
                         numerosAsInteger[var - 1] = numerosAsInteger[var]
                                      - numerosAsInteger[var - 1];
                         numerosAsInteger[var] -= numerosAsInteger[var - 1];
                  }
           }

           // Colocamos os valores embaralhados dentro do jTextArea
           for (int i = 0; i < numerosAsInteger.length; i++) {

                  if (numerosAsInteger.length == i + 1) {
                         jTextAreaResultado.append(numerosAsInteger[i].toString());
                  } else {
                         jTextAreaResultado.append(numerosAsInteger[i].toString() + ",");
                  }
           }

     }
  
  // Declaração de variáveis - não modifique//GEN-BEGIN:variables
  private javax.swing.JButton jButtonEmbaralhar;
  private javax.swing.JButton jButtonOrdenar;
  private javax.swing.JLabel jLabel4;
  private javax.swing.JLabel jLabel5;
  private javax.swing.JTextArea jTextAreaResultado;
  private javax.swing.JTextField jTextFieldNumeros;
  // Fim da declaração de variáveis//GEN-END:variables
  
}
Listagem 5. Fembalhar final

Neste artigo nosso foco foi demonstrar o uso do método de embaralhamento de array chamado shuffle() e como um bônus acrescentamos o método de ordenação de valores usando o algoritmo Insertion Sort.