Målgrupp

Studenter, yrkesverksamma och hobbyister som vill lära sig grunderna i Java programmering. Inga förkunskaper i programmering krävs.

Kurslängd

10 veckor, 2 timmar/vecka

Kursmaterial

  • Textbok: "Introduction to Java Programming" av Y. Daniel Liang
  • Online-resurser
  • Kodexempel och övningsuppgifter

Lärare

  • Jakob Andersson
  • jakob@jakobia.se

Kursmål

  • Förstå grunderna i programmering och objektorienterad design
  • Kunna skriva, kompilera och köra Java-program
  • Kunna använda grundläggande datastrukturer som arrayer och strängar
  • Förstå hur man använder och skapar metoder och klasser i Java

Kursinnehåll

Vecka 1: Introduktion till Java och Programmering

  • Vad är programmering?
  • Installation av Java och IDE (Integrated Development Environment)
  • Skriva och köra det första Java-programmet ("Hello, World!")

Vecka 2: Variabler och datatyper

  • Int, float, double, char, String
  • Aritmetiska operationer
  • Inmatning och utmatning

Vecka 3: Kontrollstrukturer

  • If-satser
  • Loopar (for, while, do-while)

Vecka 4: Funktioner och metoder

  • Funktioners syntax och anrop
  • Returnering av värden

Vecka 5: Objektorienterad programmering (Del 1)

  • Klasser och objekt
  • Konstruktorer
  • Instansvariabler och metoder

Vecka 6: Objektorienterad programmering (Del 2)

  • Arv och polymorfism
  • Abstrakta klasser och interfaces

Vecka 7: Arrayer och ArrayList

  • Endimensionella och flerdimensionella arrayer
  • ArrayList och generiska datatyper

Vecka 8: Felhantering och undantag

  • Try-catch block
  • Egendefinierade undantag

Vecka 9: In- och utmatning (I/O)

  • Läsning och skrivning av textfiler
  • Läsning och skrivning av binära filer

Vecka 10: Projekt och Examination

  • Mini-projekt: Bygg ett enkelt Java-program (t.ex. en kalkylator eller en texteditor)

Kostnad

  • Gratis

För mer information, kontakta [jakob@jakobia.se].

Vecka 1: Introduktion till Java och Programmering

Vad är Programmering?

Programmering är processen att skriva, testa och underhålla kod som utgör ett program eller en applikation. Koden består av instruktioner som utförs av en dator för att utföra en viss uppgift eller lösa ett problem. Programmering kan vara allt från att skapa en enkel hemsida till att utveckla komplexa programvarusystem, dataspel eller artificiell intelligens.

Grundläggande Komponenter

  1. Språk: Programmerare använder programmeringsspråk som Java, Python, C++, och många fler för att skriva sin kod.
  2. Algoritmer och Logik: Programmering kräver en förståelse för hur man löser problem systematiskt, vanligtvis genom att använda algoritmer.
  3. Datastrukturer: Dessa är sätt att organisera och lagra data i programmet, och kan inkludera arrayer, listor, träd och hashtabeller bland andra.
  4. Syntaks och Semantik: Varje programmeringsspråk har en unik syntaks (grammatiska regler) och semantik (betydelse eller logik) som måste följas för att datorn ska kunna förstå koden.
  5. Kontrollstrukturer: Dessa inkluderar loopar, villkorsuttryck och funktioner/metoder, och används för att styra flödet av ett program.
  6. Felsökning: En viktig del av programmering är att kunna hitta och åtgärda fel i koden, vanligtvis kallade "buggar".
  7. Kompilering och tolkning: Koden måste vanligtvis kompileras till maskinkod eller tolkas för att kunna köras på en dator.
  8. Testning: Det är viktigt att testa sin kod för att se till att den fungerar som avsett och inte har några buggar eller säkerhetshål.

Tillämpningar

Programmering används i en mängd olika tillämpningar:

  • Webbapplikationer och hemsidor
  • Dataspel
  • Vetenskaplig forskning
  • Artificiell intelligens och maskininlärning
  • Inbyggda system (till exempel i bilar, flygplan)
  • Mobilapplikationer
  • Dataanalys och visualisering
  • Och mycket mer.

Skillnader i arbetsprocessen

Programmering kan vara en individuell eller kollektiv ansträngning och kan involvera olika utvecklingsmetodiker som "vattenfall", "agil utveckling" eller "DevOps" beroende på projektets omfattning och komplexitet.

Kort sagt, programmering är en central färdighet inom datavetenskap och informationsteknologi, och den är grundläggande för utvecklingen av den moderna världen.

Installation av Java och IDE (Integrated Development Environment)

Inledning

Denna beskrivning guidar dig genom stegen för att installera Java och en Integrated Development Environment (IDE) på din dator. En IDE är en programvara som tillhandahåller en rad verktyg för att underlätta programmering, inklusive en textredigerare för att skriva kod, felsökning, och andra funktioner som hjälper till att bygga applikationer effektivt.

Förberedelser

  1. Operativsystem: Kontrollera att du har ett stödande operativsystem. De flesta versioner av Windows, macOS och Linux stöds.
  2. Hårddiskutrymme: Kontrollera att du har tillräckligt med ledigt utrymme på din hårddisk. Ca 500 MB bör vara tillräckligt.
  3. Internetanslutning: En stabil internetanslutning krävs för nedladdningar.

Steg-för-steg Guide

Installera Java Development Kit (JDK)

  1. Nedladdning: Gå till Oracle’s officiella hemsida och ladda ner den senaste versionen av Java Development Kit (JDK) för ditt operativsystem.
  2. Installation: Dubbelklicka på den nedladdade filen och följ installationsguiden. Acceptera licensavtalet och välj installationsmappen.
  3. Miljövariabler: För Windows-användare, lägg till JDK:s bin-katalog till din PATH-miljövariabel. För macOS och Linux brukar detta oftast göras automatiskt.

Installera en IDE

Det finns flera IDEs att välja mellan. Här fokuserar vi på Eclipse och IntelliJ IDEA som är populära för Java-utveckling.

Eclipse

  1. Nedladdning: Besök Eclipse officiella hemsida och ladda ner installationsfilen.
  2. Installation: Dubbelklicka på den nedladdade filen och följ installationsguiden.

IntelliJ IDEA

  1. Nedladdning: Besök IntelliJ IDEA:s officiella hemsida och ladda ner installationsfilen.
  2. Installation: Dubbelklicka på den nedladdade filen och följ installationsguiden.

Bekräfta Installationen

  1. Java: Öppna ett terminalfönster och skriv java -version. Om du ser en versionsspecifikation har installationen lyckats.
  2. IDE: Starta din IDE och skapa ett nytt Java-projekt eller öppna ett exempelprojekt för att säkerställa att allt fungerar som det ska.

Slutsats

Grattis, nu har du installerat både Java och en IDE och är redo att börja programmera!

Ditt första Java-program

Med JDK installerat är det dags att skriva ditt första Java-program. Traditionellt börjar programmerare med ett "Hello, World!" program. Detta enkla program skriver ut meddelandet "Hello, World!" till konsolen.

  1. Skapa en fil: Skapa en fil med namnet HelloWorld.java.
  2. Skriv koden:
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}
  1. Kompilera programmet: Öppna en terminal eller kommandotolk och navigera till mappen där du sparade din fil. Kör kommandot javac HelloWorld.java för att kompilera din kod.
  2. Kör programmet: Efter framgångsrik kompilering, kör ditt program med kommandot java HelloWorld. Du bör se "Hello, World!" skrivas ut till konsolen.

Förståelse av Java-syntax

Java-program består av klasser och metoder, och all kod skrivs inom dessa strukturer. Låt oss bryta ner det grundläggande "Hello, World!" programmet:

  • Klassdeklaration: public class HelloWorld definierar en klass, som är en mall för objekt. public specifierar att klassen är tillgänglig för andra klasser.
  • Metoddeklaration: public static void main(String[] args) definierar huvudmetoden, som är ingångspunkten för alla Java-applikationer. String[] args är en parameter som tar emot argument från kommandoraden.
  • Utskrift: System.out.println("Hello, World!"); är en metodanrop som skriver ut en sträng till konsolen.

Vecka 2: Variabler och datatyper

Variabeldeklaration och Initialisering

Variabler är en av de mest grundläggande och viktiga koncepten inom programmering, inklusive i Java. De fungerar som behållare som lagrar data som kan ändras under programmets körning. Variablerna tillåter programmerare att namnge datavärden, vilket gör koden lättare att förstå och underhålla. I detta avsnitt kommer vi att dyka djupare in i variablernas värld, utforska deras egenskaper, hur de deklareras, olika datatyper, och deras användning i Java.

För att använda en variabel i Java måste du först deklarera den genom att ange dess datatyp följt av variabelns namn. Du kan även initialisera variabeln i samband med deklarationen genom att tilldela den ett värde.

int age = 30; // Deklaration och initialisering av en variabel av typen int
String name = "Alice"; // Deklaration och initialisering av en variabel av typen String

Namngivning av Variabler

Namngivning av variabler är underkastat några regler och konventioner:

  • Namnet kan innehålla bokstäver, siffror, understrykningar (_) och dollartecken ($), men får inte börja med en siffra.
  • Namn är skiftlägeskänsliga, vilket innebär att age och Age är två olika variabler.
  • Namn bör vara beskrivande, vilket gör koden mer läsbar och underhållbar.
  • Java använder camelCase för namngivning av variabler, där första ordet börjar med liten bokstav och varje efterföljande ord med stor bokstav utan mellanslag, exempelvis myAge, userName.

Datatyper

Java är ett statiskt typat språk, vilket innebär att varje variabel måste deklareras med en specifik datatyp. Det finns två huvudtyper av datatyper i Java: primitiva datatyper och referenstyper.

Primitiva Datatyper

Primitiva datatyper är inbyggda i språket och representerar enkla värden. De inkluderar:

  • Heltalstyper: byte (8 bitar), short (16 bitar), int (32 bitar), long (64 bitar)
  • Flyttalstyper: float (32 bitar), double (64 bitar)
  • Teckentyp: char (16 bitar, används för att representera Unicode-tecken)
  • Sanningsvärdestyp: boolean (representerar sanningsvärdena true eller false)

Referenstyper

Referenstyper lagrar referenser (adresser) till objekt istället för själva datavärdena. Den vanligaste referenstypen är String, som används för att representera text. Andra referenstyper inkluderar klasser, gränssnitt, och arrayer.

Variabelns Räckvidd

Variablens räckvidd (scope) refererar till den del av koden där variabeln är tillgänglig för användning. I Java bestäms räckvidden av var variabeln deklareras:

  • Lokala variabler: Deklareras inom en metod och är endast tillgängliga inom den metoden.
  • Instansvariabler (medlemsvariabler): Deklareras utanför en metod men inom en klass. De är tillgängliga för alla metoder i klassen, men kräver ett objekt av klassen för att kunna användas.
  • Klassvariabler (statiska variabler): Deklareras som statiska inom en klass. De tillhör klassen snarare än något specifikt objekt och kan nås direkt med klassens namn.

Konstantvariabler

I vissa fall vill du kanske ha variabler vars värde inte kan ändras under programmets körning. I Java deklareras dessa variabler som konstanter med hjälp av nyckelordet final.

final int MAX_AGE = 100;

Att använda variabler på rätt sätt är avgörande för att skapa effektiv och underhållbar kod. Genom att förstå och tillämpa olika typer av variabler och deras räckvidd, kan du skapa mer flexibla och robusta Java-program.

Vecka 3: Kontrollstrukturer

If-satser

If-satser används för att utföra olika åtgärder baserade på om ett visst villkor är sant eller falskt. En if-sats kan hjälpa ditt program att ta beslut baserat på användarens input, resultat av beräkningar eller andra logiska villkor.

Syntaxen för en if-sats i Java är som följer:

if (villkor) {
    // Kodblock som exekveras om villkoret är sant
}

Om villkor utvärderas till sant, kommer kodblocket inuti if-satsen att köras. Om villkor är falskt, kommer kodblocket att hoppas över.

Det går också att lägga till en else-del för att hantera fallet då villkoret inte är sant:

if (villkor) {
    // Kodblock som exekveras om villkoret är sant
} else {
    // Kodblock som exekveras om villkoret är falskt
}

För mer komplexa beslut kan else if användas för att testa flera villkor:

if (villkor1) {
    // Kodblock som exekveras om villkor1 är sant
} else if (villkor2) {
    // Kodblock som exekveras om villkor2 är sant
} else {
    // Kodblock som exekveras om inget av de ovanstående villkoren är sant
}

Loopar

Loopar används för att upprepa ett kodblock flera gånger. Java stöder flera olika typer av loopar, inklusive for, while och do-while.

For-loopar

En for-loop är användbar när antalet iterationer är känt på förhand. Syntaxen för en for-loop är:

for (initiering; villkor; uppdatering) {
    // Kodblock som upprepas
}
  • Initiering: Sätter upp en loopvariabel.
  • Villkor: Loopar så länge detta villkor är sant.
  • Uppdatering: Uppdaterar loopvariabeln efter varje iteration.

Exempel:

for (int i = 0; i < 5; i++) {
    System.out.println("i är nu " + i);
}

While-loopar

En while-loop fortsätter att köra så länge villkoret är sant. Den är användbar när antalet iterationer inte är känt på förhand.

while (villkor) {
    // Kodblock som upprepas
}

Exempel:

int i = 0;
while (i < 5) {
    System.out.println("i är nu " + i);
    i++;
}

Do-While-loopar

En do-while-loop är lik while-loopen, men den garanterar att kodblocket körs minst en gång eftersom villkoret testas efter kodblocket har körts.

do {
    // Kodblock som upprepas
} while (villkor);

Exempel:

int i = 0;
do {
    System.out.println("i är nu " + i);
    i++;
} while (i < 5);

Vecka 4: Funktioner och metoder

Vad är metoder i Java?

I Java är en metod en samling uttalanden som utför en specifik uppgift. Metoder används för att utföra vissa åtgärder och de kan returnera ett värde till kallande kod. Genom att definiera och använda metoder kan en programmerare bryta ner problemet i mindre delar, vilket gör koden mer hanterbar, läsbar och återanvändbar.

En metod i Java definieras inom en klass och den kan utföra någon operation och sedan returnera ett resultat. Metoder kan ta noll eller flera parametrar, som är data som metoden kan bearbeta. Syntaxen för att deklarera en metod i Java är följande:

modifier returnTyp metodNamn(parameterLista) {
    // metodkropp
}
  • Modifier - Anger åtkomstnivån för metoden (t.ex., public, private).
  • ReturnTyp - Datatypen av värdet metoden returnerar. Om metoden inte returnerar något värde används nyckelordet void.
  • MetodNamn - Namnet på metoden.
  • ParameterLista - En lista med noll eller flera parametrar som metoden tar emot, separerade med kommatecken. Varje parameter består av en datatyp följt av ett variabelnamn.

Exempel på en enkel metod

Låt oss titta på ett enkelt exempel för att bättre förstå hur metoder fungerar i Java.

public class Calculator {

    // Metod för att addera två tal
    public static int add(int num1, int num2) {
        return num1 + num2;
    }

    public static void main(String[] args) {
        int sum = add(5, 3);
        System.out.println("Summan är: " + sum);
    }
}

I exemplet ovan har vi en klass Calculator med en metod add som tar två parametrar (num1 och num2) och returnerar summan av dessa två tal. I main-metoden anropas add-metoden med två argument (5 och 3), och resultatet (summan) skrivs ut till konsolen.

Funktioner vs. Metoder

Termerna "funktion" och "metod" används ofta omväxlande, men i kontexten av Java refererar vi oftast till dessa operationer som metoder, eftersom de är definierade inom en klass och agerar på data som är associerad med klassen eller dess instanser. I andra programmeringsspråk som inte är objektorienterade, såsom C, används termen "funktion" mer frekvent.

Vikten av metoder i Java

Metoder spelar en nyckelroll i Java-programmering av flera anledningar:

  • Återanvändbarhet - Genom att definiera kod som utför en specifik uppgift i en metod, kan den koden lätt återanvändas på flera ställen i programmet, vilket minskar redundans.
  • Modularitet - Metoder hjälper till att dela upp ett program i mindre, hanterbara segment. Detta gör det lättare att förstå, underhålla och felsöka koden.
  • Abstraktion - Genom att använda metoder kan programmerare skapa en enkel gränssnitt mot mer komplex kod. Användaren av metoden behöver inte förstå den inre mekaniken för att använda den.

Parametrar och argument

Termerna "parameter" och "argument" används ofta i samband med metoder. En parameter är en variabel som deklareras av metoden och tar emot ett värde när metoden anropas. Ett argument är det faktiska värdet som skickas till metoden vid anropet. I exemplet ovan är num1 och num2 parametrar till add-metoden, medan 5 och 3 är argumenten som skickas till metoden vid anropet.

Slutsats

Metoder i Java erbjuder ett kraftfullt sätt att organisera och återanvända kod. Genom att förstå hur man skapar och använder metoder, kan Java-programmerare skapa mer effektiva, modulära och lättförståeliga program. Som nybörjare i Java är det viktigt att få en fast grund i dessa koncept för att kunna bygga på mer avancerade ämnen i framtiden. Metoder är grunden för objektorienterad programmering i Java och utgör en viktig del av språkets kraft.

Vecka 5: Objektorienterad programmering (Del 1)

  • Klasser och objekt
  • Konstruktorer
  • Instansvariabler och metoder

Klasser och Objekt

Klasser i Java kan ses som en ritning eller en mall baserad på vilken individuella objekt skapas. En klass definierar de egenskaper (variabler) och beteenden (metoder) som dess objekt kommer att ha. Tänk dig till exempel en klass som heter Bil. Denna klass kan innehålla egenskaper såsom färg, märke, och maxhastighet samt metoder som accelerera() och bromsa().

public class Bil {
    String färg;
    String märke;
    int maxhastighet;

    void accelerera() {
        // Kod för att accelerera bilen
    }

    void bromsa() {
        // Kod för att bromsa bilen
    }
}

Ett objekt är en instans av en klass. När vi skapar ett objekt av klassen Bil, använder vi klassens definition för att allokera minne för objektets egenskaper och definiera dess metoder. Varje objekt har sin egen uppsättning värden för dess egenskaper som skiljer det från andra objekt av samma klass.

Bil minBil = new Bil();
minBil.färg = "Blå";
minBil.märke = "Volvo";
minBil.maxhastighet = 180;

Konstruktorer

En konstruktor är en speciell typ av metod i Java som används för att initialisera nya objekt. Konstruktorn har samma namn som klassen och kan ta argument för att sätta objektets initiala tillstånd.

public class Bil {
String färg;
String märke;
int maxhastighet;
// Konstruktor
Bil(String färg, String märke, int maxhastighet) {
    this.färg = färg;
    this.märke = märke;
    this.maxhastighet = maxhastighet;
}}// Skapa ett nytt Bil-objekt med hjälp av konstruktorn
Bil minBil = new Bil("Blå", "Volvo", 180);

Notera användningen av this-nyckelordet. Detta hänvisar till det aktuella objektet och används för att skilja mellan instansvariabler och parametrar med samma namn.

Instansvariabler

Instansvariabler är de egenskaper som definieras inom en klass och som varje objekt av klassen har en egen kopia av. I exemplet med Bil-klassen är färg, märke, och maxhastighet alla instansvariabler. Värdena för dessa variabler kan variera mellan olika instanser (objekt) av klassen.

Metoder

Metoder definierar beteendet hos objekten av en klass. De är funktioner som kan utföra operationer på objektets data (instansvariabler) eller utföra andra uppgifter. I Bil-exemplet representerar accelerera() och bromsa() klassens beteenden.

Metoder kan också ta parametrar, returnera värden och interagera med andra objekt och klasser.

public class Bil {
    int hastighet = 0;

    void accelerera(int ökning) {
        hastighet += ökning;
    }

    int getHastighet() {
        return hastighet;
    }
}

Sammanfattning

Klasser och objekt är hjärtat i Java och objektorienterad programmering. De tillåter programmerare att skapa moduler och återanvändbara kodblock som kan hantera komplexa uppgifter. Konstruktorer, instansvariabler, och metoder spelar alla en viktig roll i att definiera hur dessa objekt skapas, deras egenskaper och deras beteenden. Att förstå dessa koncept är avgörande för att bli en effektiv Java-programmerare och för att kunna utnyttja kraften i objektorienterad design.

Vecka 6: Objektorienterad programmering (Del 2)

Arv och polymorfism

Abstrakta klasser och interfaces

Vecka 6 i en grundkurs i Java fokuserar ofta på fördjupad förståelse av objektorienterad programmering, med särskilt fokus på koncept som arv, polymorfism, abstrakta klasser och interfaces. Dessa koncept är centrala byggstenar i objektorienterad design och programmering, och förståelsen för dem är avgörande för att skapa välstrukturerad, återanvändbar och underhållbar kod. Låt oss utforska dessa koncept mer detaljerat.

Arv

Arv är en av de grundläggande principerna i objektorienterad programmering. Det möjliggör för en klass att ärva fält och metoder från en annan klass. I Java används nyckelordet extends för att etablera ett arvsförhållande mellan två klasser. Arv främjar kodåteranvändning och skapar en hierarkisk klassificering.

Tänk dig en grundläggande klass kallad Fordon som representerar alla typer av fordon. Den kan ha egenskaper som hastighet och färg, samt en metod för att visaInfo() som skriver ut fordonets egenskaper.

class Fordon {
    protected int hastighet;
    protected String färg;

    public Fordon(int hastighet, String färg) {
        this.hastighet = hastighet;
        this.färg = färg;
    }

    public void visaInfo() {
        System.out.println("Hastighet: " + hastighet + " Färg: " + färg);
    }
}

En Bil klass kan ärva från Fordon för att använda dess egenskaper och metoder, och även lägga till egna specifika egenskaper.

class Bil extends Fordon {
    private int antalDörrar;

    public Bil(int hastighet, String färg, int antalDörrar) {
        super(hastighet, färg);
        this.antalDörrar = antalDörrar;
    }

    @Override
    public void visaInfo() {
        super.visaInfo();
        System.out.println("Antal dörrar: " + antalDörrar);
    }
}

Polymorfism

Polymorfism är konceptet att en metod kan utföra olika funktioner baserat på objektet som den tillhör. Detta uppnås genom överlagring (method overloading) och överskridning (method overriding).

Överskridning innebär att en underklass ger en specifik implementation av en metod som är ärvt från en överklass. I exemplet ovan överskrevs visaInfo()-metoden i Bil klassen för att visa ytterligare information.

Abstrakta klasser

En abstrakt klass är en klass som inte kan instansieras. Den används som en bas för andra klasser. Abstrakta klasser kan innehålla både abstrakta metoder (utan implementation) och konkreta metoder (med implementation). Abstrakta metoder måste överskridas av subklasserna.

abstract class Däggdjur {
    public abstract void göraLjud();
}

class Hund extends Däggdjur {
    @Override
    public void göraLjud() {
        System.out.println("Vov!");
    }
}

Interfaces

Ett interface i Java är en referenstyp som kan innehålla konstanter och deklarationer av abstrakta metoder. Genom att implementera ett interface kan en klass förbinda sig till att förse implementationer av de metoder som interfacet deklarerar. Ett interface används för att specificera ett set av metoder som en klass måste implementera.

interface Vattenlevande {
    void simma();
}

class Fisk implements Vattenlevande {
    @Override
    public void simma() {
        System.out.println("Fisken simmar");
    }
}

Genom att använda arv och polymorfism kan vi skapa ett flexibelt och återanvändbart kodsystem. Abstrakta klasser och interfaces tillåter oss att definiera kontrakt för vad ett objekt kan göra, utan att specificera hur det

Vecka 7: Arrayer och ArrayList

  • Endimensionella och flerdimensionella arrayer
  • ArrayList och generiska datatyper

Vecka 7 i en programmeringskurs markerar ofta en övergång till mer avancerade koncept och strukturer inom programvaruutveckling. Under denna vecka fokuserar vi på att förstå och tillämpa arrayer och ArrayLists, samt introducerar begreppet generiska datatyper. Dessa koncept är grundläggande för att hantera samlingar av data på ett effektivt sätt inom programmering. Vi kommer att utforska både endimensionella och flerdimensionella arrayer, skillnaden mellan arrayer och ArrayLists, samt hur och varför man använder generiska datatyper.

Endimensionella Arrayer

Endimensionella arrayer är den enklaste formen av arrayer och kan ses som en linjär sekvens av element där varje element kan nås via ett index. Tänk på det som en rad med brevlådor, där varje brevlåda har ett unikt nummer. I programmeringssammanhang skapar vi en endimensionell array för att lagra en samling av element av samma datatyp.

Exempelvis, om vi vill lagra fem heltal, kan vi skapa en array av typen int med en storlek av fem. I Java, skulle detta se ut så här:

int[] numbers = new int[5];

Här är int[] deklarationen av en array som innehåller heltal, numbers är namnet på arrayen, och new int[5] skapar arrayen med plats för fem heltal.

Flerdimensionella Arrayer

Flerdimensionella arrayer tar konceptet med arrayer ett steg vidare och tillåter oss att skapa tabeller eller till och med högre dimensioner av data. En vanlig användning av tvådimensionella arrayer är att representera matriser eller tabeller där vi använder två index för att nå ett specifikt element, ett för raden och ett för kolumnen.

För att skapa en tvådimensionell array i Java som kan lagra heltal, kan du göra så här:

int[][] matrix = new int[5][5];

Här skapar int[][] en tvådimensionell array, och new int[5][5] anger att vår matris (eller tabell) kommer att ha 5 rader och 5 kolumner.

ArrayList och Generiska Datatyper

Till skillnad från arrayer, som har en fast storlek, är ArrayList en del av Java's Collection ramverk som tillåter dynamiska samlingar. Det innebär att du kan lägga till, ta bort, och hantera data på ett mer flexibelt sätt. En viktig aspekt av ArrayList är möjligheten att använda generiska datatyper, vilket innebär att du kan specificera vilken typ av objekt din ArrayList ska innehålla.

En ArrayList kan skapas så här:

ArrayList list = new ArrayList<>();

Här är ArrayList deklarationen av en ArrayList som endast kommer att innehålla strängar. Användningen av är ett exempel på en generisk datatyp, där String anger typen av element som listan kan innehålla.

Generiska Datatyper

Generiska datatyper är en kraftfull funktion i Java som tillåter programmerare att skriva flexibel och återanvändbar kod. Genom att använda generiska, kan du skapa klasser, gränssnitt, och metoder med en "platshållare" för datatyper. Dessa platshållare ersätts sedan med konkreta datatyper när koden körs de implementerar Comparable-gränssnittet. Denna förmåga att arbeta med generiska datatyper är central för att bygga robusta och flexibla programvarusystem.

Användning av Generiska Datatyper med ArrayList

Användningen av generiska datatyper är särskilt användbar när det kommer till samlingar som ArrayList. Genom att specificera en datatyp vid skapandet av en lista, kan du säkerställa att listan endast innehåller objekt av den specificerade typen. Detta hjälper till att undvika ClassCastException vid körningstid och gör din kod mer typsäker.

För att illustrera, låt oss utvidga det tidigare exemplet med ArrayList:

ArrayList numbers = new ArrayList<>();
numbers.add(1); // OK
numbers.add(2); // OK
// numbers.add("text"); // Kompilatorfel, försöker lägga till en sträng till en lista av heltal

Här specificerar att ArrayListen numbers endast kommer att acceptera Integer-objekt. Försöker man lägga till ett objekt av en annan typ, som en String, resulterar det i ett kompileringsfel, vilket bidrar till högre kodkvalitet och minskar risken för fel.

Fördelar och Nackdelar

Att förstå både arrayer och ArrayList samt användningen av generiska datatyper erbjuder flera fördelar men kommer också med vissa begränsningar.

Fördelar:

  • Flexibilitet: ArrayList erbjuder dynamisk storleksändring, vilket gör dem mer flexibla än arrayer.
  • Typsäkerhet: Genom att använda generiska datatyper kan du skapa mer typsäker kod som är mindre benägen för körningstidsfel.

Vecka 8: Felhantering och undantag

  • Try-catch block
  • Egendefinierade undantag

Grundläggande Om Undantag

I Java är undantag händelser som stör programmets normala flöde. De kan uppstå på grund av en rad olika orsaker, som felaktig data, externa resurser som inte är tillgängliga, eller försök att utföra operationer som inte är tillåtna. Java hanterar dessa situationer genom att "kasta" ett undantag, vilket effektivt signalerar att något har gått fel.

Typer av Undantag

Java skiljer mellan två huvudtyper av undantag: kontrollerade (checked) och okontrollerade (unchecked) undantag.

  • Kontrollerade Undantag: Dessa är undantag som måste hanteras (eller förklaras) av koden. De används för att hantera förutsägbara men okontrollerbara fel som filen inte finns eller externa resurser inte är tillgängliga. Ett exempel är IOException.
  • Okontrollerade Undantag: Dessa undantag behöver inte explicit hanteras av koden och indikerar vanligtvis programmeringsfel, som felaktig typkonvertering eller null pekare. Exempel på okontrollerade undantag inkluderar NullPointerException och IndexOutOfBoundsException.

Hantera Undantag

Java använder try-catch block för att hantera undantag. Kod som kan kasta ett undantag placeras inom try-blocket, och catch-blocket specificerar vilken typ av undantag som ska fångas och hur det ska hanteras.

try {
    // Kod som kan kasta ett undantag
} catch (ExceptionType name) {
    // Kod för att hantera undantaget
}

För mer specifik hantering kan du ha flera catch-block för att fånga olika typer av undantag.

Använda Finally

finally-blocket är ett block som alltid utförs efter try-blocket, oavsett om ett undantag kastades eller inte. Det är användbart för att städa upp resurser, som att stänga filströmmar eller databasanslutningar, oavsett utfallet av try-blocket.

try {
    // Kod som kan kasta ett undantag
} catch (ExceptionType e) {
    // Hantera undantaget
} finally {
    // Städa upp kod som alltid körs
}

Skapa Egna Undantag

I vissa fall kan det vara användbart att skapa egna undantag. Detta gör du genom att definiera en klass som ärver från Exception (för kontrollerade undantag) eller RuntimeException (för okontrollerade undantag). Detta tillåter dig att skräddarsy hur dina undantag hanteras och ge mer specifik feedback till användaren eller systemet.

public class MyCustomException extends Exception {
    public MyCustomException(String message) {
        super(message);
    }
}

Du kan sedan använda throw-nyckelordet för att kasta ditt egna undantag när en specifik situation uppstår.

Bästa Praxis

  • Använd undantag endast för exceptionella fall, inte för vanlig kontroll av flödet.
  • Fånga endast de undantag du faktiskt kan hantera.
  • Använd alltid finally-blocket för att frigöra resurser.
  • Undvik att använda för många generiska undantag, som Exception eller RuntimeException, eftersom det kan göra felsökningen svårare.
  • När du skapar egna undantag, se till att inkludera användbar information i undantagsmeddelandena.

Genom att effektivt använda Java:s undantagshantering kan du bygga mer stabila och felresistenta applikationer. Det är en viktig färdighet för alla Java-utvecklare att förstå och implementera korrekt hantering av undantag i sina program.

Vecka 9: In- och utmatning (I/O)

  • Läsning och skrivning av textfiler
  • Läsning och skrivning av binära filer

Grundläggande om Java I/O

Java I/O är organiserat kring två huvudhierarkier: InputStream och OutputStream för byte-orienterad I/O (till exempel för att hantera binärfiler eller nätverkskommunikation), och Reader och Writer för tecken-orienterad I/O (till exempel för att hantera textfiler).

  • Byte-orienterad I/O: Används för att läsa och skriva binär data. De grundläggande klasserna inkluderar FileInputStream och FileOutputStream.
  • Tecken-orienterad I/O: Används för att läsa och skriva text. De grundläggande klasserna inkluderar FileReader och FileWriter.

Hantering av filer

För att läsa från och skriva till filer i Java, kan du använda FileInputStream och FileOutputStream för binär data, eller FileReader och FileWriter för textfiler.

Läsning från filer

Här är ett exempel på hur du kan läsa text från en fil med FileReader:

try (FileReader fr = new FileReader("exempel.txt")) {
    int i;
    while ((i = fr.read()) != -1) {
        System.out.print((char) i);
    }
} catch (IOException e) {
    e.printStackTrace();
}

Skrivning till filer

För att skriva text till en fil med FileWriter:

try (FileWriter fw = new FileWriter("exempel.txt")) {
    fw.write("Hej från Java!");
} catch (IOException e) {
    e.printStackTrace();
}

Buffrad I/O

Buffrade strömmar används för att förbättra prestandan vid in- och utmatning genom att minska antalet läs- och skrivoperationer till den underliggande enheten. I Java kan du använda BufferedReader och BufferedWriter för detta syfte.

Läsning med BufferedReader

try (BufferedReader br = new BufferedReader(new FileReader("exempel.txt"))) {
    String line;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}

Skrivning med BufferedWriter

try (BufferedWriter bw = new BufferedWriter(new FileWriter("exempel.txt"))) {
    bw.write("Hej från Java igen!");
} catch (IOException e) {
    e.printStackTrace();
}

Serialisering av Objekt

Objektserialisering är processen att omvandla ett objekt till en byteföljd så att det kan sparas till en fil eller skickas över ett nätverk. Det motsatta, deserialisering, är processen att omvandla byteföljden tillbaka till ett objekt.

Exempel på Serialisering

try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("obj.dat"))) {
    out.writeObject(mittObjekt);
} catch (IOException e) {
    e.printStackTrace();
}

Exempel på Deserialisering

try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("obj.dat"))) {
    MittObjekt obj = (MittObjekt) in.readObject();
} catch (IOException | ClassNotFoundException e) {
    e.printStackTrace();
}

Nätverks-I/O

Java's nätverks-APIer, specifikt Socket och ServerSocket, tillåter program att kommunicera över nätverket. En Socket representerar en nätverksanslutning mellan två maskiner. En server skapar en ServerSocket för att lyssna efter inkommande anslutningar, och en klient använder en Socket för att initiera kommunikationen.

Enkel Server

try (ServerSocket serverSocket = new ServerSocket(9999)) {
    Socket clientSocket = serverSocket.accept();
    PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
    out.println("Hej från servern!");
} catch (IOException e) {
    e.printStackTrace();
}

Enkel Klient

try (Socket socket = new Socket("localhost", 9999)) {
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    System.out.println(in.readLine());
} catch (IOException e) {
    e.printStackTrace();
}

Denna översikt av in- och utmatning i Java täcker grundläggande tekniker och mönster för att hantera filer, buffrar, objektserialisering, och nätverkskommunikation. Att bemästra dessa koncept är avgörande för att utveckla sofistikerade Java-applikationer som effektivt kan hantera datainmatning och -utmatning.

Vecka 10: Projekt och Examination

  • Mini-projekt: Bygg ett enkelt Java-program (t.ex. en kalkylator eller en texteditor)

Att bygga ett enkelt Java-program är ett utmärkt sätt att tillämpa de kunskaper du har samlat på dig under kursens gång. I detta mini-projekt ska vi skapa en grundläggande kalkylator. Den här kalkylatorn kommer att kunna utföra enkla aritmetiska operationer som addition, subtraktion, multiplikation, och division. Vi kommer att gå igenom hela processen steg för steg, från design till implementering.

Steg 1: Planera Kalkylatorns Funktionalitet

Innan vi börjar koda, låt oss definiera vad vår kalkylator ska kunna göra:

  • Ta emot två tal som input från användaren.
  • Låta användaren välja vilken aritmetisk operation som ska utföras: addition, subtraktion, multiplikation, eller division.
  • Visa resultatet av den valda operationen.

Steg 2: Skapa Gränssnittet

För detta projekt kommer vi att skapa ett enkelt textbaserat gränssnitt i terminalen. I framtida projekt kan du utforska grafiska användargränssnitt (GUI) med Swing eller JavaFX.

Steg 3: Implementera Logiken

Vi kommer att implementera vår kalkylator i en klass med namnet SimpleCalculator. Den kommer att ha metoder för varje aritmetisk operation och en metod för att köra programmet.

Kod för SimpleCalculator

Låt oss börja med att skriva koden:

import java.util.Scanner;

public class SimpleCalculator {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("Välkommen till Enkel Kalkylator!");

        System.out.print("Ange första talet: ");
        double firstNumber = scanner.nextDouble();

        System.out.print("Ange andra talet: ");
        double secondNumber = scanner.nextDouble();

        System.out.println("Välj operation: +, -, *, /");
        String operation = scanner.next();

        switch (operation) {
            case "+":
                System.out.printf("Resultat: %.2f\n", add(firstNumber, secondNumber));
                break;
            case "-":
                System.out.printf("Resultat: %.2f\n", subtract(firstNumber, secondNumber));
                break;
            case "*":
                System.out.printf("Resultat: %.2f\n", multiply(firstNumber, secondNumber));
                break;
            case "/":
                if (secondNumber == 0) {
                    System.out.println("Fel: Division med noll.");
                } else {
                    System.out.printf("Resultat: %.2f\n", divide(firstNumber, secondNumber));
                }
                break;
            default:
                System.out.println("Ogiltig operation.");
                break;
        }

        scanner.close();
    }

    public static double add(double first, double second) {
        return first + second;
    }

    public static double subtract(double first, double second) {
        return first - second;
    }

    public static double multiply(double first, double second) {
        return first * second;
    }

    public static double divide(double first, double second) {
        if (second == 0) {
            throw new IllegalArgumentException("Division med noll är inte tillåtet.");
        }
        return first / second;
    }
}

Steg 4: Testa Programmet

När du har skrivit koden, kompilera och kör programmet för att se till att det fungerar som förväntat. Testa med olika indata och se till att alla operationer ger korrekta resultat. Var också uppmärksam på hanteringen av division med noll, vilket inte är tillåtet och bör ge ett felmeddelande.

Sammanfattning

Grattis! Du har nu skapat en enkel kalkylator i Java. Detta mini-projekt introducerade dig till grundläggande programmeringskoncept som input och output, aritmetiska operationer, kontrollstrukturer som switch, och exceptionhantering. Att bygga små program som detta är ett utmärkt sätt att förstärka dina programmeringsfärdigheter och tillämpa teoretiska koncept i praktiken. Framöver kan du utforska mer avancerade projekt och även gränssnittsdesign för att göra dina program ännu mer användarvänliga.

Certifikat

Ta ett gratis test för att få ett certifikat: https://jakobia.se/java-basic-test/