Esta es la segunda versión del impresionantemente burdo tutorial de Python a Java. Decidí cambiar de plataforma y dejarlo en este blog porque sí.
Esta guía tiene como objetivo hacer la transición de aprender un nuevo lenguaje de programación de forma un poco más llevadera. En particular, para aprender lo básico de Java y comenzar a resolver desde ya problemas de programación competitivos. Esta guía está pensada para los cursos CC400[1-4] - Taller de Programación {A,B,C,D}.
Considere el siguiente ejemplo en Python que calcula el perímetro de un rectángulo:
En Java, para lograr el mismo resultado, hay que cambiar algunas cosas:
Java es un lenguaje orientado a objetos con tipos estáticos, a diferencia de Python que los tipos son dinámicos. Esto quiere decir, entre otras cosas, que en Java cada variable, función o método (función de clase) debe llevar "anotado" el tipo de dato que es. En el ejemplo anterior, las variables "largo" y "ancho" son de tipo entero (int-eger), y el tipo de retorno (el perímetro) también es de tipo entero. En Python no es necesario declarar esto, ya que el intérprete se encarga de determinar los tipos de las variables en tiempo de ejecución. Sin embargo, en Java es necesario anotar con anticipación los tipos, ya que estos son chequeados en tiempo de compilación (ya que Java es compilado, más de esto más abajo).
En Java existen tipos primitivos y objetos (como en Python). Los tipos primitivos son los tipos "básicos", como números (enteros o reales), los booleanos (true y false), caracteres ('a', 'b', 'c', etc.), entre otros. Algunos de estos tipos son:
float, número "real", con precisión de 32 bits.
double, número "real", con (doble) precisión de 64 bits.
boolean, valores lógicos: true y false.
char, un caracter (no confundir con un String, que es un objeto).
Existen muchos objetos útiles en Java. Uno de los más básicos es el String:
Hay muchos otros objetos que serán de utilidad, más de esto en otro post. Note que la forma de imprimir en la consola es un poco distinta.
En Python teníamos listas, tuplas, diccionarios, colecciones. En Java también las hay, un poco más burocráticas de usar. Pero hay una estructura más simple (más liviana y rápida) que será extremadamente útil: los arreglos.
Un arreglo es un espacio en memoria donde podemos guardar varios elementos del mismo tipo, como una lista, pero de tamaño fijo. Es decir, si queremos un arreglo más grande, debemos crear uno nuevo, y añadir los elementos antiguos (de hecho, esto es lo que hacen las listas de Python cuando se llenan).
Usar los arreglos es sencillo, pero siempre hay que tener cuidado con los índices de éste. Los arreglos se indizan desde 0, por lo que un arreglo de N elementos tiene índices desde el 0 hasta el N-1.
Otra observación: al crear un arreglo, los elementos no necesariamente están inicializados. Por ejemplo, al crear un arreglo de arreglos (una matriz), cada elemento del arreglo (que también es un arreglo) debe ser inicializado a su vez. En el caso de los enteros y los booleanos, estos parten con un valor por defecto de 0, o false, respectivamente.
A diferencia de Python, Java es un lenguaje "compilado" (no en el sentido de C o C++, pero obviaremos esto para términos prácticos). Esto quiere decir que para ejecutar un programa en Java, debemos primero compilarlo y luego ejecutarlo. Y "otra cosa" más.
Para compilar un programa en Java, en la consola debemos usar el comando javac. Para ejecutar, usamos java.
Para instalar Java en Windows, descargar el JDK (Java Development Kit) desde aquí y luego seguir las instrucciones de este enlace. Si no, se puede escribir y compilar código online desde alguno de los varios servicios disponibles (como éste). Si tiene Linux o Mac, de seguro ya sabe cómo instalar Java.
La "otra cosa" es que a diferencia de Python, no podemos poner el código en cualquier parte en Java. Aquí casi todo es un objeto, y la manera de ejecutar programas es dentro de un objeto. Pero para solucionar este problema, existe una función especial llamada main, en la cual se ejecuta el programa principal. A continuación, un código resumen de todo lo dicho.
O esta plantilla para empezar a programar:
La entrada y salida corresponden a lo que el programa va a leer del "usuario" (o de otro programa) y lo que va a escribir como resultado (en la consola), respectivamente. Esto es absolutamente importante para los problemas competitivos, que usualmente van a especificar una entrada y una salida para evaluar y correr el programa.
Este es el primer intento para leer y escribir:
Este programa lo que hace es escribir en consola todo lo que se le envíe por la misma:
La forma de terminar el programa es envíandole el caracter "fin de archivo" (esto se consigue presionando Control+D en Linux o Mac), lo que el programa interpreta como "null", y se rompe el ciclo.
Por varias razones no es conveniente usar la forma que mostré más arriba para escribir. Acceder a la entrada y salida es un proceso lento y costoso para un programa, por lo que es necesario optimizar este proceso. Si el problema a resolver tiene 0.1 segundo de límite de tiempo, no podemos darnos el lujo de usar el 90% de ese tiempo sólo leyendo y escribiendo, por dar un ejemplo.
Una forma conveniente de resolver esto es no imprimir (escribir) en pantalla cada vez que se tenga un resultado, sino guardarlo y finalmente escribir todo junto al final:
¿Cuál es la diferencia con la forma anterior? ¿Por qué no usar un String y concatenar cada linea al mismo String en cada iteración, en vez de usar algo tan raro como un StringBuilder? Para esto último, ver este link.
Para terminar, un último truco. ¿Qué pasa si deben leer una línea de este estilo?
5 1 2 3 4 5
7 9 8 7 6 5 4 4
El formato es el siguiente, en cada línea i viene un número N_i y a continuación N_i números, seguidos de un salto de línea. ¿Cómo leemos esto?
Una opción sería leer la línea entera, iterar sobre cada posición de la línea, y verificar que cada caracter corresponde a un número, verdad? Pero para simplificarnos la vida, podemos usar StringTokenizer (o String.split) y parseo de números.
Con esto, ya es posible resolver muchos problemas de distinta dificultad. Esta guía no pretende ser exhaustiva (o yo no pretendo serlo con ésta), sólo la práctica los llevará a dominar el lenguaje. Para más información, guías y tutoriales similares, les dejo unos links:
http://knuth.luther.edu/~bmiller/Java4Python/Java4Python.html
http://home.wlu.edu/~lambertk/pythontojava/index.htm
http://dcc.uchile.cl/~mquezada/cc4001/1-python-java.html (la primera versión de este tutorial, tiene un par de cosas distintas, como objetos y un par de ejercicios)
http://dcc.uchile.cl/~mquezada/cc4001/2-io.html (la segunda parte de la primera versión, sobre leer de la entrada estándar).
¿Y problemas? Pueden partir con uno muy sencillo, que aplica varias cosas vistas en este tutorial. Suerte!