Permalänk

close scanner (java)

Hej

Jag har min kod. Där använder jag scannern en del.
Jag har läst nu att folk rekomenderar att man ska stänga scannern med något i den här stilen

input.close();

Jag importerar min scanner
private Scanner input = new Scanner(System.in);

och använder den i flera metoder.
men vart stänger jag scannern?

Permalänk
Hedersmedlem

Du kanske vill kolla på om du kan strukturera om koden lite så att du har en metod där du använder din scanner. Vill du lägga upp lite kod kanske?

Skickades från m.sweclockers.com

Permalänk

nja det går inte riktigt att ha en metod där jag bara använder scannern.
jag har ett program som skapar användare, skapar mediaitems(cd,book,journal), gör ändringar på respektive sak, utför lån av items, retunerar lån etc.

så ganska många metoder som utnyttjar scannern.

jag har några metoder som hanterar input av string, int och andra variablar.
till exempel:

private String readString(String prompt) { System.out.print(prompt); return input.nextLine(); } private int readInt(String prompt) { System.out.print(prompt); String in; int number = 0; boolean correctInput = false; while (!correctInput) { in = input.nextLine(); try { number = Integer.parseInt(in); correctInput = true; } catch (NumberFormatException e) { correctInput = false; System.out.print("Not a number, try again \n> "); } } return number; }

vad jag lärt mig är att inte importera scannern mer än en gång per klass, onödigt att repetera kod som jag kan göra en gång.

Permalänk
Medlem
Skrivet av hjarterkung:

nja det går inte riktigt att ha en metod där jag bara använder scannern.
jag har ett program som skapar användare, skapar mediaitems(cd,book,journal), gör ändringar på respektive sak, utför lån av items, retunerar lån etc.

så ganska många metoder som utnyttjar scannern.

jag har några metoder som hanterar input av string, int och andra variablar.
till exempel:
...

vad jag lärt mig är att inte importera scannern mer än en gång per klass, onödigt att repetera kod som jag kan göra en gång.

Att importera Scanner gör du med raden

import java.util.Scanner;

Vad du menar är att du återanvänder en Scanner-instans vilket inte är samma sak.
Att skapa en instans görs vanligtvis med nyckelordet "new". En instans är ett objekt av en given klass.

Du ska inte vara rädd för att skapa objekt. Att återanvända dem kan vara både rätt och fel, ibland beroende på var och hur det görs. Det är inte fel att göra så i detta fallet men det kan vara bra att känna till vad som är vad

Att objekt skapas är alltid inte helt glasklart. Exempelvis skapas ett nytt String-objekt när du sätter ihop två Strings. I många fall är du tvungen att skapa nya objekt löpande. Säg att ditt program låter användaren skriva in ett filnamn som sedan läses från disk och skrivs ut på skärmen, och sedan frågar användaren om nästa fil. Under detta scenario kommer du vilja skapa nya objekt varje gång en fil ska läsas in.

Hursomhelst, Scanner.close() stänger den underliggande strömmen, vilket i ditt fall är System.in. När System.in väl stängts en gång i ditt program kommer du inte kunna läsa in nya tecken från tangentbordet.

System.in stängs automatiskt när ditt program avslutas så i detta fall behöver du inte stänga Scanner.

Om du istället hade använt en Scanner runt en FileInputStream hade du behövt stänga Scanner för att frigöra resurser som hålls öppna. Du kan även stänga FileInputStream:en direkt om du har en referens till den, men din Scanner-instans kommer att hamna i ett osäkert tillstånd.

Visa signatur

Kom-pa-TI-bilitet

Permalänk

aha man tackar. då behöver jag inte bry mig om detta i just mitt fall.
och ja jag skrev lite tokigt om det där med att importera scannern....

men är det fel att till exempel lägga till det i en metod såhär?

private Address readAddress() { String streetName = readString("Street name: "); int streetNo = readInt("Street Number: "); String zipCode = readString("Zip Code: "); String city = readString("City: "); Address address = new Address(streetName, streetNo, zipCode, city); input.close(); return address; }

eller

private void createReader() { String name = readString("Name: "); int readerID = readInt("Reader ID: "); int birthYear = readInt("Birth Year: "); Address address = readAddress(); PhoneNo phoneNo = readPhoneNo(); Email email = readEmail(); Reader theNewReader = new Reader(name, readerID, birthYear, address, phoneNo, email); library.addReader(theNewReader); System.out.println("Reader " + name + " added"); input.close(); }

Jag går snart upp för en extra bedömning med min lärare.
Och jag letar sätt att trimma koden så den ser lite bättre ut än vid första tillfället.
Ta bort onödiga saker och hitta nya saker som kan ge ett plus i kanten

Permalänk
Medlem
Skrivet av hjarterkung:

aha man tackar. då behöver jag inte bry mig om detta i just mitt fall.
och ja jag skrev lite tokigt om det där med att importera scannern....

men är det fel att till exempel lägga till det i en metod såhär?

private Address readAddress() { String streetName = readString("Street name: "); int streetNo = readInt("Street Number: "); String zipCode = readString("Zip Code: "); String city = readString("City: "); Address address = new Address(streetName, streetNo, zipCode, city); input.close(); return address; }

eller

private void createReader() { String name = readString("Name: "); int readerID = readInt("Reader ID: "); int birthYear = readInt("Birth Year: "); Address address = readAddress(); PhoneNo phoneNo = readPhoneNo(); Email email = readEmail(); Reader theNewReader = new Reader(name, readerID, birthYear, address, phoneNo, email); library.addReader(theNewReader); System.out.println("Reader " + name + " added"); input.close(); }

Jag går snart upp för en extra bedömning med min lärare.
Och jag letar sätt att trimma koden så den ser lite bättre ut än vid första tillfället.
Ta bort onödiga saker och hitta nya saker som kan ge ett plus i kanten

Jag vill med tydlighet säga att det är helt fel att stänga input inuti en metod som inte har något med den att göra. Exempelvis kommer du inte kunna köra dina två metoder i följd eftersom du i bägge stänger inmatningskällan.

edit: tilläggningsvis borde kanske din createReader()-metod returnerar en Reader istället för void. När man läser metodnamnet tänker man att den skapar en Reader, men man får ingenting tillbaka från metoden.

Detta är förvirrande; vad händer med Readern? Svaret är att man inte vet utan att titta på koden. Även om du själv vet att den stoppas i en lista är det inte tydligt genom att bara titta på koden vid anropningsstället:

System.out.println("Nu skapar vi en reader: "); createReader(); System.out.println("Vad hände..?");

Genom att ändra så att metoden istället returnerar en Reader får du mer flexibilitet. Du kan själv välja om du vill lägga den i din lista, eller om du vill göra något annat med den:

System.out.println("Nu skapar vi en reader: "); Reader reader = createReader(); System.out.println("Lägger till en Reader med namn " + reader.getName() + " i bibliotekslistan!"); library.addReader(reader);

Visa signatur

Kom-pa-TI-bilitet

Permalänk

okej tack

Permalänk

förstår inte riktigt vad du menar med det du la till (om createReader metoden).

Såhär ser hela koden ut gällande att skapa en reader.

Sju klasser
MainLibraryProgram
Library
ReaderCollection
Reader
Address
PhoneNo
Email

private void createReader() { String name = readString("Name: "); int readerID = readInt("Reader ID: "); int birthYear = readInt("Birth Year: "); Address address = readAddress(); PhoneNo phoneNo = readPhoneNo(); Email email = readEmail(); Reader theNewReader = new Reader(name, readerID, birthYear, address, phoneNo, email); library.addReader(theNewReader); System.out.println("Reader " + name + " added"); }

private ReaderCollection readerCollection = new ReaderCollection(); public void addReader(Reader reader) { readerCollection.addReader(reader); }

private List<Reader> readers = new ArrayList<Reader>(); public void addReader(Reader reader) { readers.add(reader); }

klasserna Reader, Address, PhoneNo, Email definierar då vad en reader är.

Jag tänker såhär att i LibraryMainProgram
skapar jag en reader (createReader).
sedan lägger jag till reader i listan med (addReader)

menar du att om jag har en metod som definierar hur en ny reader ska se ut (dvs sätter värden till variablar).
retunerr sedan en reader.
så kan jag med en annan metod plocka upp denna reader och göra vad jag vill med... antingen använda till att addReader
eller att använda till något annat om jag kommer på något

Permalänk
Medlem

Antar att du i din main har någon form av loop som printar ut en meny där man får välja vad man ska göra, samt någon form av input för att avbryta och stänga ner programmet. Isf skapa scannern innan loopen och stäng den efter loopen när man är färdig med programmet. Alternativt try-finally runt skiten.

Visa signatur

Spelrigg: 800D| i7 3930K@4,7 GHz - Custom WC | 32 GB Kingston HyperX Beast | 7970 GHz X-Edition |1x30 Dell U3011, 2x27" | Sennheiser HD650 | Xonar Essence STX |
Laptop: G74SX 17,3" 120 Hz 3D |
Server: Phenom II X4 955BE | Corsair XMS3 8 GB | 16 HDDs, 27 TB |
HTPCs: ASUS EEE Box 1.8 Ghz | Blu-Ray | OCZ Vertex 2 60 GB | 4 GB RAM |

Permalänk
Medlem
Skrivet av hjarterkung:

förstår inte riktigt vad du menar med det du la till (om createReader metoden).
...
menar du att om jag har en metod som definierar hur en ny reader ska se ut (dvs sätter värden till variablar).
retunerr sedan en reader.
så kan jag med en annan metod plocka upp denna reader och göra vad jag vill med... antingen använda till att addReader
eller att använda till något annat om jag kommer på något

Ja ungefär, fast du behöver inte ens använda en annan metod för att behandla readern. Du är fri att göra vad du vill med den.

Din addReader() ser väldigt onödig ut förresten, varför inte bara anropa readerCollection.addReader() direkt? Det är också en metod

Visa signatur

Kom-pa-TI-bilitet

Permalänk

ja jag har en loop som printar en meny och en switch för att köra menyn.
scannern skapar jag i början av klassen utanför all metoder.

så du menar att jag skulle stänga scannern i denna metoden?

private void start() { createTestReaders(); //endast för att testa programet och slippa skapa nya varje gång. createTestItem(); System.out.println("---------------Welcome to The Library" + "---------------\n---------Please select your " + "preferd option.--------\n"); while (true) { printMenu(); handleMenuCommand(); } }

Permalänk
Skrivet av Teknocide:

Ja ungefär, fast du behöver inte ens använda en annan metod för att behandla readern. Du är fri att göra vad du vill med den.

Din addReader() ser väldigt onödig ut förresten, varför inte bara anropa readerCollection.addReader() direkt? Det är också en metod

Ja, jag kan inte svara på riktigt varför jag går via Library... Den agerar mer eller mindre som en router/switch till hela programet.

Eftersom jag har ett UML diagram som jag utgår ifrån när jag gör mitt program så var detta den enklaste vägen som jag förstod det samt att min lärare tyckte det var bra.
Till en början hade jag inte det på detta vis och då fick jag smäll på fingrarna och jag la då till Library klassen.

Här är mitt UML diagram
http://imgur.com/EYMph

Permalänk
Medlem
Skrivet av hjarterkung:

Ja, jag kan inte svara på riktigt varför jag går via Library... Den agerar mer eller mindre som en router/switch till hela programet.

Eftersom jag har ett UML diagram som jag utgår ifrån när jag gör mitt program så var detta den enklaste vägen som jag förstod det samt att min lärare tyckte det var bra.
Till en början hade jag inte det på detta vis och då fick jag smäll på fingrarna och jag la då till Library klassen.

Här är mitt UML diagram
http://imgur.com/EYMph

Oj vilket maffigt diagram

Då förstår jag att Library behöver en addReader. Däremot verkar du inte behöva en ReaderCollection-klass. Det går att representera den med en privat HashTable<Reader> i Library.

Tycker det ser bra ut ändå, lycka till!

Skickades från m.sweclockers.com

Visa signatur

Kom-pa-TI-bilitet

Permalänk

ReaderCollection är mest där för att representera en databas om jag nu skulle göra ett stort program.
Idag är den lite fjuttig med bara sin arrayList.
Fast det var ett bra upplägg enligt läraren när han bedömde diagramet då vi visar hur man skulle kunna göra om programet skulle vara större och mer avancerat.

Permalänk

java - hjälp med en if sats

En sak som slog mig gällande min kod.
Jag saknar möjlighet att säga åt användaren att skapa ett unikt ID, när metoden createReader körs.

Jag har metoden searchReader och då söker den efter ID.
Så den kan jag använda för att kolla om id jag försöker använda för att skapa en reader redan finns.
Men det jag fastnar på är hur jag formulerar en if sats med detta.

så här ser min searchReader metod ut.

public Reader searchReader(int readerID) { for (Reader reader : readers) { if (reader.getReaderID() == readerID) { return reader; } } return null; }

såhär ser min createReader metod ut.

private void createReader() { String name = readString("Name: "); int readerID = readInt("Reader ID: "); int birthYear = readInt("Birth Year: "); Address address = readAddress(); PhoneNo phoneNo = readPhoneNo(); Email email = readEmail(); Reader theNewReader = new Reader(name, readerID, birthYear, address, phoneNo, email); library.addReader(theNewReader); System.out.println("Reader " + name + " added"); }

Jag tänker mig att jag ska kunna göra såhär i createReader metoden.

private void createReader() { String name = readString("Name: "); int readerID = readInt("Reader ID: "); Reader reader = library.searchReader(readerID); if (readerID == reader){ System.out.println("That reader ID does already exist, try again."); }else{ int birthYear = readInt("Birth Year: "); Address address = readAddress(); PhoneNo phoneNo = readPhoneNo(); Email email = readEmail(); Reader theNewReader = new Reader(name, readerID, birthYear, address, phoneNo, email); library.addReader(theNewReader); System.out.println("Reader " + name + " added"); } }

Kan du ge mig en hint om vad jag behöver göra för att få det att fungera?

Permalänk
Medlem

private void createReader() { String name = readString("Name: "); int readerID = readInt("Reader ID: "); for (Reader reader : readers) { if (reader.getReaderID() == readerID) { System.out.println("That reader ID does already exist, try again."); return; } } int birthYear = readInt("Birth Year: "); Address address = readAddress(); PhoneNo phoneNo = readPhoneNo(); Email email = readEmail(); Reader theNewReader = new Reader(name, readerID, birthYear, address, phoneNo, email); library.addReader(theNewReader); System.out.println("Reader " + name + " added"); }

Permalänk

doh tack för ett väldigt direkt svar.
det löste saken snabbt och nu när jag ser det är det super självklart.

Permalänk

um detta såg så bra ut, men det går inte

försöker nu med

Reader reader = library.searchReader(readerID); if (reader.getReaderID() == readerID){ System.out.println("That ID does already exist."); }

Permalänk

Lösning åsido. Kan rekommendera dig en hashmap att lagra saker i.
Den låter dig hämta en reader i konstant tid. Du anger vilket readerID du vill ha och om den finns får du den, annars får du tillbaka null.
Självklart behöver inte en hashmap vara det bästa för det du gör men för både createReader och searchReader fungerar den utan problem.

Map<Integer,Reader> hs = new HashMap<Integer,Reader>(); hs.put(readerID,reader); hs.get(readerID);

Fungerar perfekt då man sällan behöver loopa över alla utan jobbar specifikt med ett visst kännt element i taget.

Permalänk

tack för tipset. tyvärr ska jag redovisa imorgon och vill inte ändra för mycket i koden

jag söker nu bara efter lösningen på detta.

just nu funkar detta:

private void createReader() { String name = readString("Name: "); int readerID = readInt("Reader ID: "); Reader reader = library.searchReader(readerID); if (reader.getReaderID() != readerID){ int birthYear = readInt("Birth Year: "); Address address = readAddress(); PhoneNo phoneNo = readPhoneNo(); Email email = readEmail(); Reader theNewReader = new Reader(name, readerID, birthYear, address, phoneNo, email); library.addReader(theNewReader); System.out.println("Reader " + name + " added"); }else{ System.out.println("That ID does already exist."); } }

det funkar till den grad att jag kan slå in ett id som redan finns och den säger då åt mig att jag inte kan skapa en användare med det ID numret.

men skapar jag en användare med ett helt nytt ID så krashar programet.
med detta fel:
Exception in thread "main" java.lang.NullPointerException
at MainLibraryProgram.createReader(MainLibraryProgram.java:330)
at MainLibraryProgram.handleMenuCommand(MainLibraryProgram.java:154)
at MainLibraryProgram.start(MainLibraryProgram.java:94)
at MainLibraryProgram.main(MainLibraryProgram.java:14)

Permalänk

searchReader returnerar null ifall det inte finns en användare. Det betyder att du anger variabeln reader till null och får på raden nedanför en nullpointer då du gör reader.getReaderID().

Kolla ifall reader är null i if-satsen istället. Det inträffar bara om en användare inte redan fanns.

Permalänk

jösses... jag har ju gjort detta på flera andra ställen och så ser jag inte lösningen
tack
tack
tack

Permalänk
Hedersmedlem

Slog ihop två av dina trådar hjarterkung då det verkar handla om samma program. Försök hålla dig till en tråd istället för att skapa en tråd för varje nya problem. Annars blir det korspostning

Citat:

§ 3.3 Det är inte tillåtet att skapa flera trådar om samma ämne, varken i samma eller olika forumdelar (så kallad korspostning). Om en moderator har låst en tråd, är det inte tillåtet att skapa en ny tråd om samma ämne.

MVH

Permalänk

ska jag debattera med en moderator... hm ja lite
Tråden har olika frågor... första handla om att stänga en scanner, nästa problem handla om en if sats.

men det är sak samma. det passar fint här då första delen ändå har besvarats och nu inte varit aktiv på ett tag.

samt nu är problem 2 löst också
god jul

Permalänk
Hedersmedlem
Skrivet av hjarterkung:

ska jag debattera med en moderator... hm ja lite
Tråden har olika frågor... första handla om att stänga en scanner, nästa problem handla om en if sats.

men det är sak samma. det passar fint här då första delen ändå har besvarats och nu inte varit aktiv på ett tag.

samt nu är problem 2 löst också
god jul

Haha klart det går bra att debattera, vi är inte hänsynslösa monster i moderatorkåren. Vi vill ju bara försöka hålla forumet trevligt och snyggt för att vi bryr oss om det och gillar det. Det är ju en fritidssyssla.

Jag förstår att det är olika frågor men bakomliggande projektet är detsamma och då kanske du får bättre hjälp om allting hanteras i en tråd. De som hjälper dig får bättre förståelse för vad du jobbar med och kan följa vad som händer enklare. Sen är det ju mer rättvist mot andra som söker hjälp, det skulle bli lite kaotiskt om det startades en tråd så fort det fanns en ny fråga men inom samma ämne.

Bra att det löst sig, dyker det upp något mer så fortsätt i den här tråden. Tycker du inte rubriken funkar så bra kan du säga till så kan vi ändra den. Det är okej att dubbelposta om du tillför ny information eller vill fråga mer. Bara du inte håller på bumpar(läs i reglerna om termen är oklar).

Permalänk

toppen
då fortsätter vi så