Avatar billede jimmyhp Nybegynder
05. november 2007 - 09:25 Der er 14 kommentarer og
2 løsninger

hashMap og arrays

Hej, her efter to måneder med programmering skal vi lave et program. Jeg er i tvivl om man kan koble hashmap og arrays sammen.

Man skal kunne ændre status for en opgave for hver person.

person  cpr  opg1 opg2 opg3...
bo      3    g    i    g
hans    6    i        g
karl    7    i  g    g
...

der er 21opg pr person og man skal kunne ændre opg 14 uden at brugeren skal skrive andet end cpr, opg og status.

kom gerne med kode-eksempler :D
Tak
Avatar billede pidgeot Nybegynder
05. november 2007 - 09:36 #1
Det kan man sagtens - du kan jo eks. lave en Person-klasse der indeholder et Array/ArrayList/whatever, samt en metode til at ændre en given opgave til en given status, og så gemme en instans pr. person i den collection der mapper fra cpr til person.

For at ændre status, henter du så den relevante instans ud af din collection, og kalder den metode du har lavet.

Jeg har egentlig ikke noget imod at lave et kodeeksempel, men du får nok mest ud af at prøve at lave det selv, og så spørge om de ting du er i tvivl om.
Avatar billede jimmyhp Nybegynder
05. november 2007 - 10:30 #2
Men det er en god ide at lave en klasse for personer (navn, cpr) fx arraylist og så et fast array til opgaver (21 faste opgaver med status)??
Avatar billede pidgeot Nybegynder
05. november 2007 - 10:52 #3
Om du skal bruge et fast array til opgavernes status afhænger af den nøjagtige opgaveformulering og hvor fleksibelt programmet skal være - med andre ord, det er noget du må tage stilling til.

Hvis du er 110% sikker på at det altid er 21 opgaver, så kan du godt bruge et array, men hvis antallet kan variere, er du nok bedre tjent med en anden form for collection med opgavens nummer som indeks (eks. en HashMap<Integer,StatusType>, eller hvad der nu er passende).

Man kunne måske endda forestille sig en Opgave-klasse, der så indeholder ekstra oplysninger om den pågældende opgave (beskrivelse, m.v.). Denne kunne du eks. bruge som indeks i Person-klassens HashMap (altså en HashMap<Opgave,StatusType>).

Du kommer jo ikke uden om en eller anden person-klasse når du også skal have navnet med - du kunne ganske vist lave noget fusk så det var et status-array der lå direkte i collectionen, men så kan du ikke have navnet med - og det bliver bare endnu mere besværligt hvis der skal mere ind på et senere tidspunkt.
Avatar billede jimmyhp Nybegynder
05. november 2007 - 13:22 #4
ja det er sikkert at der er maks 21 opgaver og dette skal ikke udvides. I opgaven strå der heller ikke noget om at personregistret skal kunne udvides, men synes bare at det ville være det mest naturlige at lave (medmindre det bliver alt for bøvlet).

Jeg er ikke helt sikker på hvordan hashmap virker. Hvis du har et link eller en god forklaring evt tegning så ville det være fint. Ved ikke rigtig hvad forskellen skulle være på en arraylist og hashmap?
Avatar billede jimmyhp Nybegynder
05. november 2007 - 20:40 #5
forresten så skal der hver gang programmet startes initialeres en status for opgaverne for hver person. Hvordan gøres det nemmest?

tak
Avatar billede pidgeot Nybegynder
05. november 2007 - 21:09 #6
I og med at du opretter en instans af person-klassen pr. person, kan du løbe gennem hans opgave-array/HashMap/whatever og sætte status.

Et HashMap fungerer ved at du kan have en vilkårlig nøgle der mapper til en værdi. En arraylist er essentielt et array der selv ændrer størrelse, men hvor elementerne altid er indekseret med 0-n, hvor n er antal-1. Da du med fordel kan bruge cpr som nøgle, giver en HashMap mening, da du jo næppe bestemmer den værdi ud fra rækkefølgen de blev oprettet (og tilmed starter fra 0).

Om du skal bruge en string eller Integer eller en helt tredje type afhænger af hvad der egner sig bedst til cpr-værdien.
Avatar billede jakoba Nybegynder
05. november 2007 - 22:01 #7
Det du vil gøre kan gøres på 1000 måder.
En af de dårligste ville nok være at "koble hashmap og arrays sammen"

Det ligner en database opgave i og med at det du skal gøre typisk ville blive gjort med en database (med 2 tabeller).

tabel: "NAVN"
  felt: cprnr  heltal
  felt: navn    streng_af_bogstaver
unik nøgle er cprnr

tabel: "status"
  felt: cprnr      heltal
  felt: opgavenr  heltal
  felt: status    ?
unik nøgle er [ cprnr, opgavenr ]

dit eksempel er så en simpel ændring (eller tilføjelse) i tabellen "status"

for den række i tabellen status
hvor  cprnr = <givet cpr>
  og  opgavenr = <givet opgavenr>
skal  status sættes til <given status>

I begge tableller bruges cprnr som nøgle (hel eller delvis) og siden cprnr er på 10 cifre ville det blive alt for langt et array hvis vi brugte arrays. Så jeg vil anbefale du bruger 2 hashmaps.

mvh JakobA
Avatar billede jimmyhp Nybegynder
05. november 2007 - 22:37 #8
#jakoba
Det var også min første tanke, eller at man kunne indlæse fra en tekstfil. Men tror mest opgaven går ud på at få arrays og diverse(pensum) nogenlunde på plads. Så den mest besværlige måde er vel lige så god som den nemmeste måde :D  Skal jo lære det skidt hehe ;P
Avatar billede pidgeot Nybegynder
05. november 2007 - 23:00 #9
Alene det at personregistret ikke behøver kunne udvides, er et godt tegn på at opgaven ikke går ud på at lære om den bedste måde at gøre tingene på, men at lære grundstenene i hvordan sproget fungerer. Man kan snildt argumentere for at kunne få en smule mere fleksibilitet, men netop en database tror jeg lidt ødelægger intentionen bag opgaven.

Der er ingen tvivl om at en database nok er den bedste måde at gøre det på, og det er jeg ikke i tvivl om vil være den første tanke når de her elever engang er færdige med uddannelsen - men når man er under uddannelse, er man engang i mellem nødt til at holde sig til de mindre gode løsninger.
Avatar billede usse Nybegynder
10. november 2007 - 14:12 #10
Ved ikke helt hvad du mener, men er det noget alla det her ?

import java.util.HashMap;

public class Skole
{
    private HashMap<Integer, Elev> elever;

    public Skole()
    {
        elever = new HashMap<Integer, Elev>();
    }
   
    public void addElev(Elev elev)
    {
        elever.put(elev.getID(), elev);
    }
   
    public String getElev(Integer id)
    {
        return elever.get(id).toString();
    }       
   
    public String getOpgave(Integer id, int opgaveNr)
    {
        return elever.get(id).getOpgave(opgaveNr);   
    }   
   
    public void setOpgave(Integer id, int opgaveNr, String opgave)
    {
        elever.get(id).setOpgave(opgaveNr, opgave);
    }   
   
   
    public static void main(String args[])
    {
        Skole skole = new Skole();
       
        Elev e1 = new Elev(1, "Hans", 21);
        Elev e2 = new Elev(2, "Jørgen", 21);
        Elev e3 = new Elev(3, "Niels", 21);
       
        skole.addElev(e1);
        skole.addElev(e2);
        skole.addElev(e3);
       
        System.out.println(skole.getElev(2));
       
        skole.setOpgave(1, 5, "En opgave beskrivelse");
        skole.setOpgave(2, 5, "En opgave beskrivelse");
        skole.setOpgave(2, 6, "En opgave beskrivelse");
       
        System.out.println(skole.getOpgave(1, 5));
        System.out.println(skole.getOpgave(2, 5));
        System.out.println(skole.getOpgave(3, 6));
    }   
}

public class Elev
{
    private Integer id;
    private String navn;
    private Opgave[] opgaver;
   
    public Elev(Integer id, String navn, int antalOpgaver)
    {
        this.id = id;
        this.navn = navn;
        opgaver = new Opgave[antalOpgaver];
    }
   
    public Integer getID()
    {
        return id;
    }   
   
    public String getNavn()
    {
        return navn;
    }       
   
    public String getOpgave(int opgaveNr)
    {
        if(opgaveNr < opgaver.length && opgaver[opgaveNr] != null)
            return opgaver[opgaveNr].getOpgave();
        else return null;
    }   
   
    public void setOpgave(int opgaveNr, String beskrivelse)
    {
        if(opgaveNr < opgaver.length)
        {   
            if(opgaver[opgaveNr] == null)
                opgaver[opgaveNr] = new Opgave(beskrivelse);
            else   
                opgaver[opgaveNr].setOpgave(beskrivelse);
        }
           
    }
   
    public String toString()
    {
        return "ID: "+id+" Navn: "+navn+" Opgaver: "+opgaver.length;
    }   
   
}

public class Opgave
{
    private String beskrivelse;
   
    public Opgave(String beskrivelse)
    {
        this.beskrivelse = beskrivelse;
    }
   
    public String getOpgave()
    {
        return beskrivelse;
    }   
   
    public void setOpgave(String beskrivelse)
    {
        this.beskrivelse = beskrivelse;
    }   
   
}
Avatar billede jimmyhp Nybegynder
10. november 2007 - 21:33 #11
Tak for hjælpen.. jeg lavede det i et dobbelt array :D og det virker nu.. Tror jeg har fattet systemet i OOP nu.. :D

Jeg har lige et hurtigt spørgsmål: Jeg kan ikke forstå hvorfor den smider en
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 20

arrayet er [19][21], burde den ikke stoppe løkken når i er mindre-lig array-størrelsen?
   
int i=0;
                while(i <= ARRAYS.hold[0].length)
                {
                    double count1 = 0, count2, count3;
                    double count = 0, countug;
                    System.out.println("hej " + i);
                    //--------------------
                    //U-opgaver - dat
                    for (int j = 1; j <= 8; j++){
                        if (ARRAYS.hold[i][j] < 2){
                            count++;
                        }
                    }
                    count2 = count / 8;   
                    System.out.println("hej " + count2);
                   
                    //G-opgaver - dat
                    for (int j=9; j < 11; j++){
                        if (ARRAYS.hold[i][j] == 2)
                            count1++;
                    }
                    count3 = count1 / 2;
                    System.out.println("hej " + count3);
                   
                    //summerer de værdierne ovenfor og udskriver om den studerende må gå til eksamen
                    countug = count2 + count3;
                    System.out.println("hej " + countug);
                    if (countug >= 1.75)
                        System.out.println(ARRAYS.person[i] + "\tkan gå til eksamen i datalogi");
                    i++;
                }
Avatar billede jimmyhp Nybegynder
10. november 2007 - 21:35 #12
alle de der hej'ere var bare for at se hvor det gik galt :S hehe
Avatar billede jakoba Nybegynder
11. november 2007 - 05:23 #13
din fejl er her:
    while(i <= ARRAYS.hold[0].length)
de gyldige indeks værdier starter jo med 0 så hvis der skal være 19 celler ialt skal du slutte ved 19-1, og ikke ved 19.  Lav '<=' om til '<'
    while(i < ARRAYS.hold[0].length)

mvh JakobA
Avatar billede jimmyhp Nybegynder
12. november 2007 - 14:51 #14
fik det til at virke.. :D

Tror bare at jeg lukker den nu, hvis der er nogen der vil have point? Så må je glige se om jeg kan finde ud af at give dem til den rigtige.. :D

Tak igen..
Avatar billede pidgeot Nybegynder
12. november 2007 - 16:06 #15
Smider et svar, så må du selv bestemme om du mener jeg skal have point :)
Avatar billede usse Nybegynder
15. november 2007 - 12:35 #16
svar tata
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester