lunes, 28 de noviembre de 2011

Ordenar usando la interface Comparable

En este post revisaremos una duda que recibimos. El objetivo es leer un archivo que contiene en cada línea datos que representan una instancia. Por ejemplo el siguiente archivo (productos.txt) contiene:

555 Producto1 200 3
333 Producto2 300 1
222 Producto3 400 2
111 Producto4 150 5

Para representar un producto, creamos una clase Producto que contiene un id, nombre, precio y cantidad en inventario. Y deseamos ordenarlo por id del producto. El tip es que la clase Producto debe implementar la interface Comparable para que podamos comparar entre productos y de esta forma puedan ser ordenados.

El siguiente código muestra cómo ordenar el archivo anterior (copiar el código en un archivo con nombre OrdenarArchivo.java), los pasos son muy sencillos:

  1. leemos cada línea del archivo y la dividimos en los campos de un producto (se asume que los campos están separados por un espacio en blanco);
  2. creamos una instancia de Producto y la agregamos a una lista de Productos;
  3. ordenamos la lista usando Collections.sort

Es importante notar que tras bambalinas Collections.sort está usando el método compareTo (de la interface Comparable) que implementamos en la clase Producto. Al ejecutar el código debe imprimir:

Elementos originales:
[555 Producto1 200.0 3, 333 Producto2 300.0 1, 
222 Producto3 400.0 2, 111 Producto4 150.0 5]
Elementos ordenados:
[111 Producto4 150.0 5, 222 Producto3 400.0 2, 
333 Producto2 300.0 1, 555 Producto1 200.0 3]

OrdenarArchivo.java

import java.io.*;
import java.util.*;

public class OrdenarArchivo{
  public static void main(String [] args){
    String filename = "productos.txt";
    String linea = null;
    String[] datos = null;
    List<Producto> productos = new ArrayList<Producto>();
    Producto producto = null;
    try{
      BufferedReader br = new BufferedReader(
                           new FileReader(filename)); 
      // leer todas la lineas del archivo
      while((linea=br.readLine())!=null){
        // cada linea tiene los datos para crear un producto
        datos = linea.split(" ");
        producto = new Producto(
                    Integer.parseInt(datos[0]),
                    datos[1],
                    Double.parseDouble(datos[2]),
                    Integer.parseInt(datos[3]));
        // agregamos el producto a la lista de productos
        productos.add(producto);
      }
      br.close();
      // imprimir archivo en orden original
      System.out.println("Elementos originales:");
      System.out.println(productos);
      Collections.sort(productos);
      // imprimir archivo ordenado
      System.out.println("Elementos ordenados:");
      System.out.println(productos);
    }catch(IOException e){
      System.out.println(e);   
    }
  }
}

// Clase que representa lo que queremos ordenar
// Notar que estamos implementado Comparable
class Producto implements Comparable<Producto> {
  int id;
  String nombre;
  double precio;
  int inventario;
  
  public Producto(int id, String nombre, 
                  double precio, int inventario){
    this.id = id;
    this.nombre = nombre;
    this.precio = precio;
    this.inventario = inventario;
  }
  
  public String toString(){
    return id + " " + nombre + " " + 
           precio + " " + inventario;
  }
  
  // Este metodo es el que nos permite comparar
  // entre productos y de esta forma puedan ser ordenados.
  public int compareTo(Producto p){
    return id - p.id;
  }
}

2 comentarios: