Ejemplo Clases


// Voy a crear una clase para almacenar productos
// EL producto tiene un nombre, un precio y un stock
// Cuando creo el producto obligatoriamente le tengo que dar un nombre
// El stock y el precio por defecto valen 0
// Voy a crear una función PVP que me devuelve el precio  más el iva
// Voy a crear una función comprar que me añade una cantidad al stock
public class Producto {
	String nombre;
	double precio;
	int stock;
	
	Producto(String nombre){
		this.nombre=nombre;
		precio=0;
		stock=0;
	}
	
	double PVP() {
		return precio*1.21;
	}
	void comprar(int cantidad) {
		stock+=cantidad;
	}

}
public static void main(String[] args) {
		Producto tuerca=new Producto("Tuerca");
		tuerca.precio=20;
		System.out.println(tuerca.PVP());
		tuerca.comprar(30);
		System.out.println(tuerca.stock);
		tuerca.comprar(30);
		System.out.println(tuerca.stock);
		
		Producto misterio;
		misterio=tuerca;
		
		System.out.println(misterio.stock); // ¿? 0 60 error 
		
		misterio.comprar(40);
		
		System.out.println(tuerca.stock); // 0 20 no existe 60 100 10000
		System.out.println(misterio==tuerca);
	}

Constructores

package com.trifulcas.oop;

// La sintaxis de una clase es muy sencilla 'class'
public class Alumno {
	// Propiedades
	String nombre;
	// 2) Para obligar a dar valor a alguna propiedad
	// El constructor de alumno requiere de un parámetro
	// de tipo String. Esto quiere decir que cuando 
	// cree un objeto alumno le tendré que pasar un nombre
	Alumno(String nombre){
		// ¿Qué es this? This hace referencia al propio objeto
		// Por qué aquí hace falta y en saludo no?
		// Lo uso para diferenciar entre el parámetro y la propiedad
		this.nombre=nombre;
	}
	// Funciones
	void saludo() {
		System.out.println(this.getSaludo() + this.nombre);
		// Sin this también funciona ¿Por qué?
		// Porque Java por defecto busca funciones y propiedades en this
		System.out.println(getSaludo() + nombre);
	}
	String getSaludo() {
		return "Hola que tal ";
	}
}
public class Coche {
	String marca;
	int velocidad=0;
	
	public Coche(String marca) {
		super();
		this.marca = marca;
	}
	void acelerar() {
		System.out.println("brum brum");
		// Lo interesante de las clases es que sus funciones
		// Pueden acceder y modificar las propiedades
		velocidad+=10;
	}
	void frenar() {
		System.out.println("Ñññic");
		
		velocidad-=10;
		if (velocidad<0) {
			velocidad=0;
		}
	}
}


public class Cuadrado {
	// Cada objeto cuadrado tendrá su lado
	double lado;

	// COnstructor: es una función especial que se llama
	// Cuando creamos (instanciamos) el objeto
	// se llama igual que la clase
	// ¿Para qué se usa?
	// 1) Para inicializar valores de mis propiedades
	// 2) Para obligar a dar valor a alguna propiedad
	Cuadrado() {
		lado=1;
	}

	// Todas las funciones devuelven el valor en función
	// de la propiedad de la clase, no como un parámetro
	double area() {
		return lado * lado;
	}

	double perimetro() {
		return lado * 4;
	}

	double diagonal() {
		return Math.sqrt(lado * lado * 2);
	}
}

public static void main(String[] args) {
		// String es la plantilla y cadena es un objeto
		// Cada cadena es una instancia de la clase String
		String cadena = "Hola que tal";
		String otracadena = "Hola que tal";
		String yotracadena = "Hola que tal";
		// Como cada objeto es instancia de la clase String
		// Todos comparten las mismas propiedades y funciones
		System.out.println(cadena.length());
		System.out.println(otracadena.length());
		System.out.println(yotracadena.length());

		// Yo tengo la clase Alumno
		// La clase alumno es una plantilla para crear alumnos
		// La palabra clave new es la que me crea el objeto
		Alumno ana = new Alumno("Ana Pi");
	
		ana.saludo();
		Alumno eva = new Alumno("Eva Pérez");
		
		eva.saludo();
		// juan está declarado pero no he creado ningún objeto
		// Es como si no existiera. No puedo poner juan.nombre="sss"
		Alumno juan;

		Coche seat = new Coche("Seat Panda");
		
		seat.acelerar();
		seat.acelerar();
		System.out.println(seat.velocidad);
		seat.frenar();
		seat.frenar();
		seat.frenar();
		seat.frenar();
		System.out.println(seat.velocidad);
		// Otro coche nuevo
		Coche citroen = new Coche("Citroen");
		
		for (int i = 0; i < 10; i++) {
			citroen.acelerar();
		}
		System.out.println(citroen.velocidad);

		// Esto no tiene sentido:
		// Coche.marca="Seat";
		// Las propiedades se ponen en los objetos, no en la clase
		// Porque la clase es la plantilla
		// Nosotros no usamos el plano de una casa para colgar un cuadro

		// Cada objeto que creamos de la clase cuadrado
		// Encapsula las funciones que nos dan información de su propia
		// clase. No tenemos que pasar esos valores como parámetro
		Cuadrado c1 = new Cuadrado();
		c1.lado = 2;
		System.out.println(c1.area());
		System.out.println(c1.perimetro());
		System.out.println(c1.diagonal());

		System.out.println(cadena.toUpperCase());
		
		// Yo puedo crear un ArrayList con la clase Cuadrado
		// Igual que lo hacía de string o de cualquier otra cosa
		ArrayList<Cuadrado> lista =new ArrayList<>();
		for(int i=1;i<=10;i++) {
			// Creo un objeto
			Cuadrado c=new Cuadrado();
			c.lado=i;
			// Añado a la lista
			lista.add(c);
		}
		// Recorrer esa lista
		for(Cuadrado c:lista) {
			// Imprimir el área
			System.out.println(c.area());
		}
		
		Cuadrado a=new Cuadrado();
		Cuadrado b=new Cuadrado();
		a.lado=1;
		b.lado=1;
		System.out.println(a==b); // false porque no son el mismo objeto
		
		System.out.println("Cuadrado nuevo con constructor");
		Cuadrado nuevo=new Cuadrado();
		System.out.println(nuevo.lado);
	}

Introducción OOP

// La sintaxis de una clase es muy sencilla 'class'
public class Alumno {
	// Propiedades
	String nombre;

	// Funciones
	void saludo() {
		System.out.println("Hola " + nombre);
	}
}
public class Coche {
	String marca;
	int velocidad=0;
	
	void acelerar() {
		System.out.println("brum brum");
		// Lo interesante de las clases es que sus funciones
		// Pueden acceder y modificar las propiedades
		velocidad+=10;
	}
	void frenar() {
		System.out.println("Ñññic");
		velocidad-=10;
	}
}
package com.trifulcas.oop;

public class Cuadrado {
	// Cada objeto cuadrado tendrá su lado
	double lado;
	
	// Todas las funciones devuelven el valor en función
	// de la propiedad de la clase, no como un parámetro
	double area() {
		return lado*lado;
	}
	double perimetro() {
		return lado*4;
	}
	double diagonal() {
		return Math.sqrt(lado*lado*2);
	}
}

public class Introduccion {

	public static void main(String[] args) {
		// String es la plantilla y cadena es un objeto
		// Cada cadena es una instancia de la clase String
		String cadena="Hola que tal";
		String otracadena="Hola que tal";
		String yotracadena="Hola que tal";
		// Como cada objeto es instancia de la clase String
		// Todos comparten las mismas propiedades y funciones
		System.out.println(cadena.length());
		System.out.println(otracadena.length());
		System.out.println(yotracadena.length());
		
		// Yo tengo la clase Alumno
		// La clase alumno es una plantilla para crear alumnos
		// La palabra clave new es la que me crea el objeto
		Alumno ana = new Alumno();
		ana.nombre="Ana Pi";
		ana.saludo();
		Alumno eva=new Alumno();
		eva.nombre="Eva Pérez";
		eva.saludo();
		// juan está declarado pero no he creado ningún objeto
		// Es como si no existiera. No puedo poner juan.nombre="sss"
		Alumno juan;
		
		Coche seat=new Coche();
		seat.marca="Seat Panda";
		seat.acelerar();
		seat.acelerar();
		System.out.println(seat.velocidad);
		seat.frenar();
		System.out.println(seat.velocidad);
		// Otro coche nuevo
		Coche citroen=new Coche();
		citroen.marca="Citroen";
		for(int i=0;i<10;i++) {
			citroen.acelerar();
		}
		System.out.println(citroen.velocidad);

		// Esto no tiene sentido:
		// Coche.marca="Seat";
		// Las propiedades se ponen en los objetos, no en la clase
		// Porque la clase es la plantilla
		// Nosotros no usamos el plano de una casa para colgar un cuadro

// Cada objeto que creamos de la clase cuadrado
		// Encapsula las funciones que nos dan información de su propia
		// clase. No tenemos que pasar esos valores como parámetro
		Cuadrado c1 = new Cuadrado();
		c1.lado = 2;
		System.out.println(c1.area());
		System.out.println(c1.perimetro());
		System.out.println(c1.diagonal());

		System.out.println(cadena.toUpperCase());

// Yo puedo crear un ArrayList con la clase Cuadrado
		// Igual que lo hacía de string o de cualquier otra cosa
		ArrayList<Cuadrado> lista =new ArrayList<>();
		for(int i=1;i<=10;i++) {
			// Creo un objeto
			Cuadrado c=new Cuadrado();
			c.lado=i;
			// Añado a la lista
			lista.add(c);
		}
		// Recorrer esa lista
		for(Cuadrado c:lista) {
			// Imprimir el área
			System.out.println(c.area());
		}

Cuadrado a=new Cuadrado();
		Cuadrado b=new Cuadrado();
		a.lado=1;
		b.lado=1;
		System.out.println(a==b); // false porque no son el mismo objeto
}

}

Soluciones ejercicios HashMap

package com.trifulcas.colecciones;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;

public class SolucionesColecciones {

	public static void main(String[] args) {
		HashMap<String, Integer> notas = new HashMap<>();
		notas.put("JS", 5);
		notas.put("c#", 8);
		notas.put("Java", 9);
		System.out.println(calculaMedia(notas));
		System.out.println(100 / 3.0);
		HashMap<String, ArrayList<Integer>> productos = new HashMap<>();
		productos.put("Tuerca", new ArrayList<>());
		productos.get("Tuerca").add(1);
		productos.get("Tuerca").add(2);
		productos.get("Tuerca").add(3);
		productos.put("Tornillo", new ArrayList<>(Arrays.asList(2, 3, 4)));
		productos.put("Arandela", new ArrayList<>(Arrays.asList(4, 5, 6)));
		System.out.println(productos);
		System.out.println(precioMinimo(productos));
	}

	static double calculaMedia(HashMap<String, Integer> notas) {
		double suma = 0;
		// Recorro los valores que es lo que me hace falta
		for (int nota : notas.values()) {
			suma += nota;
		}
		// Redondear a dos decimales OJO cuando en java dividimos dos enteros nos hace
		// la división entera
		// Por lo tanto quita los decimales. Si queremos conservarlos ponemos .0
		return Math.round((suma / notas.size()) * 100) / 100.0;
	}

	// Ojo con los parámetros de entrada y salida
	static HashMap<String, Integer> precioMinimo(HashMap<String, ArrayList<Integer>> productos) {
		HashMap<String, Integer> res = new HashMap<String, Integer>();
		// Recorro el hashmap
		for (String producto : productos.keySet()) {
			// Añado la clave la misma y el valor aprovecho el min de collections
			res.put(producto, Collections.min(productos.get(producto)));
			// Si no me acuerdo del collections me creo yo la función
			res.put(producto, minimoValor(productos.get(producto)));
		}
		return res;
	}
	// No hace falta pero bueno...
	static int minimoValor(ArrayList<Integer> numeros) {
		int minimo = numeros.get(0);
		for (int numero : numeros) {
			if (numero < minimo) {
				minimo = numero;
			}
		}
		return minimo;
	}
}

Ejercicios preexamen

# vamos a hacer una función a la que le pasamos un tipo de bono
# un tipo de cliente y una cantidad y nos calcule el precio de acuerdo a lo siguiente
# bono=vip precio=3000
# bono=extra precio=2000
# bono=normal precio=1000
# tipo cliente= standard, el precio no cambia
# tipo cliente=premium, el precio es la mitad
# por defecto el bono sea normal y el cliente tambien
# los parámetros por defecto siempre al final



def precioTotal(cantidad, tipoBono="normal", tipoCliente="normal"):
    if tipoBono == "normal":
        precio = 1000
    elif tipoBono == "extra":
        precio = 2000
    else:
        precio = 3000
    if tipoCliente == "premium":
        precio = precio / 2
    return cantidad * precio


print(precioTotal(10, "normal", "normal"))
print(precioTotal(10, "normal", "premium"))
print(precioTotal(10, "vip", "premium"))
print(precioTotal(10))

# esta función, en teoría, cuenta el número de pares que hay en la lista
# ¿Funciona? Si es que no por qué y como arreglarlo
def contarPares(lista):
    total=0
    for i in lista:
        if total%2==0:
            total+=i
    return total

def contarPares(lista):
    total = 0
    for i in lista:
        if i % 2 == 0:
            total += 1
    return total

# Una función a la que le pasamos un proyecto como este:
proyecto = [
    {"nombre": "Análisis", "horas": 10, "precio": 60},
    {"nombre": "Desarrollo", "horas": 50, "precio": 50},
    {"nombre": "Implementación", "horas": 5, "precio": 70},
    {"nombre": "Pruebas", "horas": 15, "precio": 40},
]
# Y nos devuelve una lita de las tareas que ocupan más de 10 horas. En el caso anterior, desarrollo y pruebas
# tareasLargas(proyecto)->["Desarrollo","Pruebas"]

def tareasLargas(proyecto):
    res=[]
    for tarea in proyecto:
        if tarea["horas"]>10:
            res.append(tarea['nombre'])
    return res
print(tareasLargas(proyecto))

# una función a la que le pasamos una cadena y nos devuelve una lista con la última letra de cada palabra
# ultimaLetra("hola que tal")->["a","e","l"]

def ultimaLetrafor(cadena):
    palabras=cadena.split()
    res=[]
    for palabra in palabras:
        res.append(palabra[-1])
    return res

def ultimaLetra(cadena):
    return [palabra[-1] for palabra in cadena.split()]
print(ultimaLetra("hola que tal"))

Soluciones ejercicios funciones

# Crear una función areaCuadrado(lado) a la que le pasamos un lado y nos devuelve el área
# areaCuadrado(2)-> 4

def areaCuadrado(lado):
    return lado*lado

# Crear una función a la que le pasamos un número y nos devuelve true si es divisible por
# 3 y false en caso contrario
# multiploTres(8)->False multiploTres(9)->True
def multiploTres(numero):
    return numero % 3==0
    """
    if numero % 3==0:
        return True
    else:
        return False
        """
# Crear una función a la que le pasamos una lista de números y nos dice
# el número de pares que hay
# numeroPares([1,2,3,4])->2
def numeroPares(lista):
    contador=0
    # recorrer la lista
    for numero in lista:
        # cada vez que haya un par contarlo
        if numero % 2 == 0:
            contador += 1
    return contador

# Crear una función a la que le pasamos una cadena y un carácter y nos devuelve una lista
# con las palabras que tienen ese caracter
# buscaCaracter("Hola que tal","a")->["hola","tal"]
# buscaCaracter("Hola que tal","u")->["que"]
def buscaCaracter(cadena,caracter):
    res=[]
    # recorrer las palabras
    for palabra in cadena.split():
        # Si en esas palabras está el caracter lo añado a res
        # Si no está, no hago nada
        if caracter in palabra:
            res.append(palabra)
    return res
# Crear una función a la que le pasamos una cadena y nos devuelve la lista de palabras
# ordenada por longitud

# TODO: Preguntar que hacer si la longitud de dos cadenas es igual
def ordenarCadena(cadena):
    # obtener la lista de palabras
    palabras=cadena.split()
    palabras=sorted(palabras,key=len)
    return palabras

Más ejemplos diccionarios anidados

# Así defino un diccionario
libro = {"titulo": "El Quijote", "autor": "Cervantes", "precio": 20}
# así accedo al valor de una clave
print(libro["precio"])
# Así recorro todas las claves
for clave in libro:
    print(clave)
    # los valores de esa clave
    print(libro[clave])
# Puedo tener una lista de diccionarios

biblioteca = [
    {"titulo": "El Quijote", "autor": "Cervantes", "precio": 20},
    {"titulo": "Las olas", "autor": "Virginia Woolf", "precio": 17},
    {"titulo": "Los detectives salvajes", "autor": "Roberto Bolaño", "precio": 23},
    {"titulo": "Tom va a la escuela", "autor": "Rick Sánchez", "precio": 10}
]

# para acceder a un elemento primero accedo a la posición de la lista
print(biblioteca[1])  # {"titulo": "Las olas", "autor": "Virginia Woolf", "precio": 17},
print(biblioteca[1]["autor"])  # "Virginia Woolf"

# Recorrer esa lista de diccionarios
for libro in biblioteca:
    print(libro)

# Quiero ver todos los autores de la biblioteca
for libro in biblioteca:
    print(libro["autor"])

# Puedo hacer cálculos por ejemplo media de precios
suma = 0
for libro in biblioteca:
    suma += libro["precio"]
print(suma / len(biblioteca))

proyecto = [
    {"nombre": "Análisis", "horas": 10, "precio": 60},
    {"nombre": "Desarrollo", "horas": 50, "precio": 50},
    {"nombre": "Implementación", "horas": 5, "precio": 70},
    {"nombre": "Pruebas", "horas": 15, "precio": 40},
]


# función que me calcule el total de importe del proyecto

def totalProyecto(proyecto):
    total = 0
    # recorro las tareas
    for tarea in proyecto:
        # Accedo a las propiedades que me interesan. En este caso horas y precio
        total += tarea["horas"] * tarea["precio"]
    return total


print(totalProyecto(proyecto))

# listas que tienen diccionarios que tienen listas de diccionarios
biblioteca = [
    {"titulo": "El Quijote",
     "autor": {"nombre": "Miguel de Cervantes", "pais": "España"},
     "ediciones": [
         {"editorial": "Alianza", "precio": 15},
         {"editorial": "Cátedra", "precio": 20}
     ]
     },
    {"titulo": "2666",
     "autor": {"nombre": "Roberto Bolaño", "pais": "Chile"},
     "ediciones": [
         {"editorial": "Anagrama", "precio": 30},
         {"editorial": "Alfaguara", "precio": 28}
     ]
     }
]

# Al precio de la primera edición de mi primer libro
print(biblioteca[0]["ediciones"][0]["precio"]) # 15
# Al precio de la segunda edición de mi segundo libro
print(biblioteca[1]["ediciones"][1]["precio"]) # 28

# Si quiero el total de precios de toda la biblioteca
# Tengo que recorrer los libros
# después recorrer las ediciones
# sumar los precios
def sumaPreciosBiblioteca(biblioteca):
    suma=0
    for libro in biblioteca:
        for edicion in libro["ediciones"]:
            suma+=edicion["precio"]
    return suma

print(sumaPreciosBiblioteca(biblioteca))

Ejemplos clase Collection

package com.trifulcas.colecciones;

import java.util.ArrayList;
import java.util.Collections;

public class EjemplosCollection {

	public static void main(String[] args) {
		ArrayList<String> nombres = new ArrayList<String>();
		nombres.add("Juan");
		nombres.add("María");

		Collections.addAll(nombres, "Pedro", "Luis");
		System.out.println("Hemos añadido elementos sueltos en una sola línea");
		System.out.println(nombres); // [Juan, María, Pedro, Luis]
		System.out.println("Invertimos el arrayList");
		Collections.reverse(nombres);
		System.out.println(nombres); // [Luis, Pedro, María, Juan]
		System.out.println("Ordenamos el arrayList");
		Collections.sort(nombres);
		System.out.println(nombres); // [Juan, Luis, María, Pedro]
		System.out.println("Si está ordenado podemos usar binarySearch");
		System.out.println(Collections.binarySearch(nombres, "Pedro"));
		System.out.println("Desordenamos el arrayList");
		Collections.shuffle(nombres);
		System.out.println(nombres); //

		// Intercambiamos los valores de dos posiciones
		Collections.swap(nombres, 1, 2);
		System.out.println("Intercambiar posición 1 y 2");
		System.out.println(nombres); //

		System.out.println("Podemos obtener el máximo");
		System.out.println(Collections.max(nombres)); //Pedro
		System.out.println("Y el mínimo");
		System.out.println(Collections.min(nombres)); //Juan
		System.out.println("Rellenar toda la lista con un valor");
		Collections.fill(nombres, "Ana");
		System.out.println(nombres);
		ArrayList<Integer> numeros=new ArrayList<>();
		Collections.addAll(numeros, 1,2,2,3,3,3,4,4,4,4);
		System.out.println("Frecuencia (numero de apariciones) de un elemento en una lista");
		System.out.println(numeros);
		
		System.out.println(Collections.frequency(numeros, 3));
	}

}

Ejemplos tipos genéricos

package com.trifulcas.colecciones;

public class EjemplosGenericos {

	public static void main(String[] args) {
		// Al ser tipo int llama a la primera función
		System.out.println(mayor(4,3));
		// Al ser tipo dobule llama a la segunda
		System.out.println(mayor(4.6,3.5));
		// Llamo a la función con parámetros de tipo double
		System.out.println(mayorG(4.6,3.5));
		// Llamo a la función con parámetros de tipo int
		System.out.println(mayorG(3,4));
		// Llamo a la función con parámetros de tipo String
		System.out.println(mayorG("ana","pep"));

	}
	// Esta función tiene de tipo int
	static int mayor(int a, int b) {
		if (a>b) { 
			return a;
		}
		return b;
	}
	// Esta función es una sobrecarga con double
	static double mayor(double a, double b) {
		if (a>b) { 
			return a;
		}
		return b;
	}
	// Aquí utilizo un tipo genérico, puedo llamar a la función
	// Con cualquier tipo (siempre que se pueda comparar, que eso es lo que significa extends Comparable<T>)
	static <T extends Comparable<T>> T mayorG(T a, T b){
		if (a.compareTo(b)>0) { 
			return a;
		}
		return b;
	}
}

Ejemplos HashSet

package com.trifulcas.colecciones;

import java.util.HashSet;

public class EjemplosHashSet {

	public static void main(String[] args) {
		// Lo creamos con HashSet igual que cualquier colección
		HashSet<String> alumnos = new HashSet<>();
		// añado los elementos con add
		alumnos.add("Ana");
		alumnos.add("Eva");
		alumnos.add("Pep");
		System.out.println("Imprimo el conjunto entero");

		System.out.println(alumnos);
		// Si añado un elemento que ya existe es como si no hiciera nada
		alumnos.add("Ana");
		System.out.println("Al añadir Ana no cambia porque ya estaba");

		System.out.println(alumnos);
		System.out.println("Contains me devuelve true porque Ana está en el conjunto");

		System.out.println(alumnos.contains("Ana"));
		System.out.println("Recorro los elementos del conjunto");

		for (String alumno : alumnos) {
			System.out.println(alumno);
		}
		System.out.println("Elimino el valor de Ana");

		alumnos.remove("Ana");
		System.out.println(alumnos);

	}

}