<jupyter_start><jupyter_text>Primero pasos con Java  Este tutorial se puede utilizar para comenzar a trabajar con Java como lenguaje de programación. Veremos una pequeña introducción y cada uno de los puntos más relevantes para empezar a programar con Java.  Introducción Java es un lenguaje de programación más populares y nació en el año 1995 con Sun Microsystem y posteriormente fue adquirido por Oracle Corporation. Para su ejecución requiere de la máquina virtual que es independiente del sistema donde se esté ejecutando.Java requiere el JDK (Java Development Kit, en español Herramientas de desarrollo para Java) instalado para poder desarrollar aplicaciones en Java. El JDK es el conjunto de librerías, paquetes, clases, métodos, etc. que incluye javac para convertir el código fuente (.java) en bytecode (.class) que será interpretado y ejecutado por la JVM (Java Virtual Machine, en español Máquina Virtual de Java). También incluye javadoc para generar la documentación de nuestro código.El JDK incluye además el JRE (Java Runtime Environment, en español Entorno de Ejecución de Java), que realmente ejecuta los programas de Java. Es posible instalar el JRE por separado, pero el JDK lo incluye.  Comentarios en JavaLos comentarios sirven para documentar nuestro código. Java nos permite crear comentarios de una única línea y de varias.<jupyter_code>// Esto es un comentario de una linea

/* Esto es 
   un comentario
   de varias líneas
*/<jupyter_output><empty_output><jupyter_text>Programa en Java básicoLa estructura básica de un programa desarrollado usando Java es la siguiente. En el ejemplo podemos observar como se crea una clase pública, es decir, que tendrás acceso a esta clase desde cualquier parte del código. El método main es un método que permite la ejecución del programa.<jupyter_code>public class NombreClase {
     public static void main (String args[]){
        // instrucciones
     }
}<jupyter_output><empty_output><jupyter_text>Objetos y clasesLa base de la Programación Orientada a Objetos es el objeto que a su vez tiene una serie de características y comportamiento. Una clase representa el conjunto de objetos que comparten características y comportamiento. En Java, las clases contienen atributos y métodos. Para cada atributo se crea un método get y set para poder gestionarlos. Además, cada clase cuentra con uno o varios constructores mediante los cuales podemos crear instancias de las clases.   Clases en JavaUna clase en Java comienza con la palabra reservada class y a continuación los atributos y métodos. La definición de una clase sigue la siguiente estructura: ```javaclass   {   //declaración de atributos  [visibilidad] [modificadores]   [= valor];  ...  //declaración de constructor  public () {    ;  }  //declaración de métodos  [visibilidad] [modificadores]  () {    ;  }  ...}``` El siguiente ejemplo muestra una clase para describir libros.<jupyter_code>//Ejemplo de clase para almacenar libros
public class Libro
{
    //Atributos de la clase
    protected int identificador;
    protected String autor;
    protected String titulo;

    //Constructor con el mismo nombre de la clase
    public Libro(){}
    
    //Constructor con parametros
    public Libro(String ptitulo, String pautor){
        this.titulo = ptitulo;
        this.autor = pautor;
    }
    
    public void setAutor(String pautor)
    {
        this.autor = pautor;
    }
    
    public void setTitulo(String ptitulo)
    {
        this.titulo = ptitulo;
    }

    public String getAutor()
    {
        return autor;
    }

    public String getTitulo()
    {
        return titulo;
    }
    
    public static String metodoEstatico(){
        return "No necesito una instancia para ejecutarme";
    }
}<jupyter_output><empty_output><jupyter_text>Una vez tenemos declarada la clase, podemos instanciar objetos llamando al constructor con la instrucción new:<jupyter_code>// declaramos los objetos
Libro libro1 = new Libro("Don Quijote de la Mancha", "M<NAME>");
Libro libro2 = new Libro("La Galatea", "<NAME>");
Libro libro3 = new Libro("El rufián dichoso", "<NAME>");
Libro libro4 = new Libro("El laberinto del amor", "<NAME>");<jupyter_output><empty_output><jupyter_text>Y podemos llamar a los métodos:<jupyter_code>// recuperamos los atributos de los libros y los mostramos por pantalla
System.out.println(libro1.getTitulo() + " - " + libro1.getAutor());
System.out.println(libro2.getTitulo() + " - " + libro2.getAutor());<jupyter_output><NAME> - <NAME>
La Galatea - <NAME><jupyter_text>Los métodos pueden ser declarados como estáticos lo que significa que no requiere de una instancia para poder ejecutarse<jupyter_code>System.out.println(Libro.metodoEstatico());<jupyter_output>No necesito una instancia para ejecutarme<jupyter_text>En el siguiente ejemplo vemos un programa completo.<jupyter_code>public class MiPrograma
{
    public static void main(String[] args)
    {
        //Creamos un animal cuyo nombré será Falco
        Libro miLibro = new Libro("El viejo celoso", "Miguel de Cervantes");
        
        //Mostraremos el titulo del libro por pantalla
        System.out.println("El titulo es: " + miLibro.getTitulo());
    }
}<jupyter_output><empty_output><jupyter_text>Salida de datosAunque Java proporciona numerosas librerías para guardar los logs en ficheros, la forma más sencilla es mostrarlo por pantalla la información.<jupyter_code>System.out.println("Hello World");<jupyter_output>Hello World<jupyter_text>PaquetesLos paquetes en Java nos permiten agrupar los componentes de nuestra aplicación que estén relacionados entre si. El paquete se declara antes de cualquier otra cosa, es decir, es la primera línea de nuestro código en una clase, por ejemplo. A continuación, añadiremos los imports, clases, etc.<jupyter_code>//package ejemplo.de.paquete;

//public class mi_clase
//{

//}<jupyter_output><empty_output><jupyter_text>Modificadores de accesoLos modificadores de acceso public, protected, default y private en Java nos proporcionan el encapsulamiento en Java que tiene como objetivo gestionar el acceso a los datos de una instancia. El modificador por defecto es default y permite el acceso a la clase como a las clases del mismo paquete. Si un atributo es privado, debemos crear los métodos set y get para poder manipular sus valores.<jupyter_code>public class Revista
{
    private int numeroArticulos; //Este atributo es privado
    private String titulo; //Contador de registro

    public void setNumeroArticulos(int n)
    {
        numeroArticulos = n;//Establecemos el valor del atributo
    }

    public int getNumeroArticulos()
    {
        return numeroArticulos;//Retornamos el valor actual del atributo
    }
}<jupyter_output><empty_output><jupyter_text>Variables y tipos de datos Una variable tiene un tipo específico y alberga un valor que puede ser inicializado y modificado durante la ejecución del programa en Java. En Java todas las variables tendrán un tipo de dato y un nombre de identificador.<jupyter_code>int a, b, c; 
float pi; 
double d; 
char a;
String cadena = "Hola";<jupyter_output><empty_output><jupyter_text>En Java podemos tener variables estáticas que indica que solo se va a crear una vez aunque tengamos muchas instancias de esa clase.<jupyter_code>class Coche {
    public final static int numeroPuertas = 4;
}

System.out.println("Número de puertas:" + Coche.numeroPuertas);<jupyter_output>Número de puertas:4<jupyter_text>CondicionalesEn Java el operador condicional AND (todas las expresiones evaluadas igual true) es && y el OR (alguna de las expresiones igual a true) operador es ||.<jupyter_code>int vble1 = 10;
int vble2 = 20;

if ((vble1 == 10) && (vble2 == 20))
  System.out.println("Las dos variables mantienen sus valores iniciales");

if ((vble1 == 10) || (vble2 ==20))
  System.out.println("Al menos una variable mantiene su valor inicial");<jupyter_output>Las dos variables mantienen sus valores iniciales
Al menos una variable mantiene su valor inicial<jupyter_text>Operador instanceofEl operador instanceof es un operador especial para los objetos mediante el cual podemos comprobar si un objeto es de una clase concreta.<jupyter_code>if (libro1 instanceof Libro)
  System.out.println("Libro");<jupyter_output>Libro<jupyter_text>Sentencias de decisiónSon sentencias que permiten tomar una decisión para ejecutar un bloque de instrucciones u otro. Las sentencias de decisión corresponden a: if-then-else y switch.<jupyter_code>if (libro1 instanceof Libro) {
  System.out.println("El objeto es de tipo Libro");
} else {
  System.out.println("El objeto no es de tipo Libro");
}<jupyter_output>El objeto es de tipo Libro<jupyter_text>BuclesLas sentencias de bucle permiten ejecutar un bloque de sentencias tantas veces como queramos hasta que se cumpla una condición.<jupyter_code>int contador = 0;
while (contador<5) {
  System.out.println("contador:" + contador);
  contador++;
}
for(contador=0;contador<5;contador++){
  System.out.println("contador:" + contador);
}<jupyter_output>contador:0
contador:1
contador:2
contador:3
contador:4<jupyter_text>FuncionesJava permite la definición de funciones para evitar el código duplicado. Java permite de forma sencilla llamar a las funciones, pasando los parámetros correspondientes.<jupyter_code>void muestraContador(int max){
  int i;
  for(i=0;i<max;i++){
    System.out.println("contador:" + i);
  }
}

muestraContador(5);<jupyter_output>contador:0
contador:1
contador:2
contador:3
contador:4<jupyter_text>Arrays en JavaUn array Java es una estructura de datos que permite almacenar un conjunto de datos de un mismo tipo. Es necesario declarar El tamaño de los arrays, no pudiendo cambiar en tiempo de ejecución.<jupyter_code>// Tenemos un array de 5 elementos.
char lista[] = {'a','b','c','d','e'};
System.out.println("Accedemos al primer elemento:" + lista[0]);<jupyter_output>Accedemos al primer elemento:a<jupyter_text>Java también permite instanciar arrays de dos dimensiones<jupyter_code>int matriz[][] = {{1,2,3},{30,20,10}};
System.out.println(matriz[1][0]); //Java empieza a contar objetos desde la posicion 0, fila 1, columna 0

for(int x = 0; x < matriz.length; x++) { 
    for (int y = 0; y < matriz[x].length; y++) { 
        System.out.println(x + "," + y + ":" + matriz[x][y]); 
    }
}<jupyter_output>30
0,0:1
0,1:2
0,2:3
1,0:30
1,1:20
1,2:10<jupyter_text>Java permite la creación de listas de objetos.<jupyter_code>List<Libro> lista = new ArrayList<Libro>();
lista.add(libro1);
lista.add(libro2);
lista.add(libro3);
lista.add(libro4);

for (int i = 0; i < lista.size(); i++) {
    System.out.println(lista.get(i).getTitulo());
}<jupyter_output><NAME> la Mancha
La Galatea
El rufián dichoso
El laberinto del amor<jupyter_text>HerenciaJava permite definir que una clase herede de otra, compartiendo atributos y métodos. Entre las diferentes ventajas de la herencia se encuentra la reutilización del código así como facilitar el mantenimiento del código. La palabra clave en Java para definir la herencia es extends.<jupyter_code>class Periodico extends Libro{
    private String fecha;
    
    public String getFecha(){
        return fecha;
    }
    
    public void setFecha(String pfecha){
        this.fecha = pfecha;
    }
}<jupyter_output><empty_output><jupyter_text>La clase anterior hereda de la clase Libro, que tiene definidos los atributos como protected y por tanto podemos acceder desde nuestra clase Periodico.<jupyter_code>Periodico periodico = new Periodico();
periodico.setFecha("2020");
periodico.setTitulo("Investigaciones geograficas");
periodico.setAutor("Universidad de Alicante");
System.out.println(periodico.getTitulo());<jupyter_output>Investigaciones geograficas<jupyter_text>Gestión de excepcionesCuando ejecutamos código Java se pueden generar excepciones ya sea por el código o el uso incorrecto de tipos, en la ejecución que debemos tener en cuenta. Cuando se produce un error Java finaliza la ejecución y genera un mensaje de error, que en Java se conoce como excepción.La instrucción **try** permite definir un bloque de instrucciones.La instrucción **catch** permite recoger cada una de las excepciones que se pueden producir y tratarlas.<jupyter_code>try {
  //  Block of code to try
}
catch(Exception e) {
  //  Block of code to handle errors
}

## Ficheros en Java
Java permite la lectura y escritura de ficheros. Java puede lanzar excepciones que debemos capturar mediante try-catch 
La siguiente función permite leer un fichero de texto y muestra su contenido.
import java.io.*;

public void leeFichero(String nombreFichero) {
    try {
        File myObj = new File(nombreFichero);
        Scanner myReader = new Scanner(myObj);
        while (myReader.hasNextLine()) {
            String data = myReader.nextLine();
            System.out.println(data);
        }
        myReader.close();
    } catch (FileNotFoundException e) {
        System.out.println("Ha ocurrido un error.");
        e.printStackTrace();
    }
}
leeFichero("fichero-ejemplo.txt");<jupyter_output>En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga antigua, rocín flaco y galgo corredor. Una olla de algo más vaca que carnero, salpicón las más noches, duelos y quebrantos los sábados, lantejas los viernes, algún palomino de añadidura los domingos, consumían las tres partes de su hacienda. El resto della concluían sayo de velarte, calzas de velludo para las fiestas, con sus pantuflos de lo mesmo, y los días de entresemana se honraba con su vellorí de lo más fino. Tenía en su casa una ama que pasaba de los cuarenta, y una sobrina que no llegaba a los veinte, y un mozo de campo y plaza, que así ensillaba el rocín como tomaba la podadera. Frisaba la edad de nuestro hidalgo con los cincuenta años; era de complexión recia, seco de carnes, enjuto de rostro, gran madrugador y amigo de la caza. Quieren decir que tenía el sobrenombre de Quijada, o Quesada, que en esto hay alguna diferencia en los autores q[...]<jupyter_text>Java también permite la escritura de ficheros con el método **createNewFile()** que devuelve **True** si puede realizar la operación y **False** en caso contrario.<jupyter_code>try {
    File myObj = new File("filename.txt");
    if (myObj.createNewFile()) {
        System.out.println("Fichero creado: " + myObj.getName());
    } else {
        System.out.println("El fichero ya existe.");
    }
} catch (IOException e) {
    System.out.println("Ha ocurrido un error.");
    e.printStackTrace();
}<jupyter_output>File created: filename.txt<jupyter_text>Para escribir en el fichero debemos usar la clase **FileWriter()** y el método **write()**. Al finalizar debemos llamar a **close()**.<jupyter_code>try {
    FileWriter myWriter = new FileWriter("filename.txt");
    myWriter.write("Escribo mi primera línea en un fichero.");
    myWriter.close();
    System.out.println("La escritura ha sido correcta.");
} catch (IOException e) {
    System.out.println("Ha ocurrido un error.");
    e.printStackTrace();
}
leeFichero("filename.txt");<jupyter_output>Escribo mi primera línea en un fichero.<jupyter_text>Crear ficheros XML<jupyter_code>import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

try {
      DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
      DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
      
      //Elemento raíz
      Document doc = docBuilder.newDocument();
      Element rootElement = doc.createElement("coleccion");
      doc.appendChild(rootElement);
      
      //Primer elemento
      Element elemento1 = doc.createElement("obra1");
      elemento1.setTextContent("Contenido de la obra 1");
      rootElement.appendChild(elemento1);
      
      //Se agrega un atributo al nodo elemento y su valor
      Attr attr = doc.createAttribute("id");
      attr.setValue("10");
      
      elemento1.setAttributeNode(attr);
      
      Element elemento2 = doc.createElement("obra2");
      elemento2.setTextContent("Contenido de la obra 2");
      rootElement.appendChild(elemento2);
      
      //Se escribe el contenido del XML en un archivo
      TransformerFactory transformerFactory = TransformerFactory.newInstance();
      Transformer transformer = transformerFactory.newTransformer();
      DOMSource source = new DOMSource(doc);
      StreamResult result = new StreamResult(new File("ejemplo.xml"));
      transformer.transform(source, result);
} catch (ParserConfigurationException pce) {
    pce.printStackTrace();
} catch (TransformerException tfe) {
    tfe.printStackTrace();
}

leeFichero("ejemplo.xml");<jupyter_output><?xml version="1.0" encoding="UTF-8" standalone="no"?><coleccion><obra1 id="10">Contenido de la obra 1</obra1><obra2>Contenido de la obra 2</obra2></coleccion><jupyter_text>Crear ficheros JSONPara trabajar con ficheros JSON necesitamos utilizar una librería externa. Existen muchas librerías y en este ejemplo vamos a utilizar **json-simple**. Si usamos maven, deberemos configurar el fichero *pom.xml* para usar esta librería. En jupyter notebooks se simula de la siguiente forma.<jupyter_code>%%loadFromPOM
<dependency>
    <groupId>com.googlecode.json-simple</groupId>
    <artifactId>json-simple</artifactId>
    <version>1.1.1</version>
</dependency>
Una vez que tenemos disponible nuestra librería JSON, ya podemos empezar a trabajar con ella.
import java.io.FileWriter;
import java.io.IOException;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

JSONObject obj = new JSONObject();
obj.put("Blog", "http://data.cervantesvirtual.com");
obj.put("Categoria", "Colecciones digitales");
obj.put("Inicio", new Integer(2015));

JSONArray list = new JSONArray();
list.add("Linked Open Data");
list.add("Jupyter notebooks");
list.add("Colecciones digitales");

obj.put("Tags", list);

try {

    FileWriter file = new FileWriter("ejemplo.json");
    file.write(obj.toJSONString());
    file.flush();
    file.close();

} catch (IOException e) {
    //manejar error
}

System.out.print(obj);<jupyter_output>{"Categoria":"Colecciones digitales","Inicio":2015,"Blog":"http:\/\/data.cervantesvirtual.com","Tags":["Linked Open Data","Jupyter notebooks","Colecciones digitales"]}
{'fraction_non_alphanumeric': 0.08777294919255325, 'fraction_numerical': 0.00740383067761146, 'mean_word_length': 4.5608591885441525, 'pattern_counts': {'":': 5, '<': 122, '<?xml version=': 1, '>': 116, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 12}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '27', 'dir': 'jupyter-structured-clean-dedup', 'id': '149171', 'license': 'Unlicense', 'n_tokens_mistral': 6104, 'n_tokens_neox': 6089, 'n_words': 1996, 'path': 'PrimerosPasosConJava.ipynb', 'repo_name': 'hibernator11/AprediendoJava', 'size': '18796'}