Reading a Binary file in java and displaying it - java

Im trying to read my binary file that i created for a country with at least 5 gold medals. When im trying to read the file and then displaying it. it shows:
?????††††††††††††††???†††††††††††††††† 27 27 38 92. It displays part of the information. This is my code at the moment:
import java.io.*;
import java.util.*;
class Pays
implements Comparable<Pays>
{
private String nom;
private int gold;
private int silver;
private int bronze;
private int sum;
public Pays(String nom,int gold,int silver, int bronze,int sum)
{
this.nom = nom;
this.gold=gold;
this.silver=silver;
this.bronze=bronze;
this.sum=sum;
}
public int compareTo(Pays autre) {
return nom.toUpperCase().trim().compareTo( autre.nom.toUpperCase().trim() );
}
public String getNom(){ return nom; }
public int getGold(){ return gold; }
public int getSilver(){ return silver; }
public int getBronze(){ return bronze; }
public int getSum(){return sum;}
public boolean equals(Object obj)
{
if (this == obj)
return true;
else
if ( ! (obj instanceof Pays))
return false;
else
{
Pays autre = (Pays) obj;
return nom.trim().equalsIgnoreCase(autre.nom.trim());
}
}
public void ecrire(DataOutputStream aCreer)
throws IOException
{
aCreer.writeBytes(nom);
aCreer.writeInt(gold);
aCreer.writeInt(silver);
aCreer.writeInt(bronze);
aCreer.writeInt(sum);
}
}
class numba3{
static LinkedList<Pays> lireCreer(String nomFichier)
throws IOException
{ LinkedList<Pays> liste = new LinkedList<Pays>();
boolean existeFichier = true ;
FileReader fr = null;
try {
fr = new FileReader (nomFichier) ;
}
catch ( java.io.FileNotFoundException erreur) {
System.out.println("Probleme d'ouvrir le fichier " +
nomFichier);
existeFichier = false ;
}
if (existeFichier) {
BufferedReader entree = new BufferedReader(fr);
boolean finFichier = false ;
while ( !finFichier ) {
String uneLigne = entree.readLine();
if (uneLigne == null)
finFichier = true ;
else {
String nom = uneLigne.substring(0, 38);
int gold = Integer.parseInt(uneLigne.substring(38,43).trim());
int silver = Integer.parseInt(uneLigne.substring(43,48).trim());
int bronze = Integer.parseInt(uneLigne.substring(48).trim());
int sum=gold+silver+bronze;
liste.add(new Pays(nom,gold,silver,bronze,sum));
}
}
entree.close();
}
return liste;
}
static void afficher(LinkedList<Pays> liste,int numero){
for(int i=0;i<numero;i++){
System.out.printf("%30s %10d %10d %10d %10d\n",liste.get(i).getNom(),liste.get(i).getGold(),liste.get(i).getSilver(),liste.get(i).getBronze(),liste.get(i).getSum());
}
}
public static void quickSort(LinkedList<Pays> liste, int low, int high) {
if (liste.isEmpty() == true || liste.size()== 0)
return;
if (low >= high)
return;
int middle = low + (high - low) / 2;
int pivot = liste.get(middle).getSum();
int i = low, j = high;
while (i <= j) {
while (liste.get(i).getSum() > pivot) {
i++;
}
while (liste.get(j).getSum() < pivot) {
j--;
}
if (i <= j) {
Pays temp=liste.get(i);
liste.set(i,liste.get(j));
liste.set(j,temp);
i++;
j--;
}
}
if (low < j)
quickSort(liste, low, j);
if (high > i)
quickSort(liste, i, high);
}
static void afficherPays(LinkedList<Pays>liste,String nom){
for(int i=0;i<liste.size();i++){
if(liste.get(i).equals(new Pays(nom, 0, 0, 0,0))){
System.out.printf("%30s %10d %10d %10d %10d\n",liste.get(i).getNom(),liste.get(i).getGold(),liste.get(i).getSilver(),liste.get(i).getBronze(),liste.get(i).getSum());
}
}
}
static void creerBinaire(LinkedList<Pays> liste, int gold,String nomBinaire)
throws IOException
{
DataOutputStream aCreer = new DataOutputStream
( new FileOutputStream(nomBinaire));
for (int i = 0; i < liste.size(); i++)
{
if ( liste.get(i).getGold() >= gold)
liste.get(i).ecrire(aCreer);
}
aCreer.close();
System.out.println("\nOn vient de creer le fichier binaire : " + nomBinaire);
}
static LinkedList<Pays> readBinaire(String nomALire)
throws IOException{
System.out.println("On lit le fichier binaire du nom " + nomALire);
LinkedList<Pays> unVect = new LinkedList<Pays> ();
DataInputStream aLire = new DataInputStream
( new FileInputStream(nomALire));
boolean finFichier = false ;
String nom = "";
int rang = 0;
while ( ! finFichier ) {
try {
for (int i = 0; i < 19; i++)
nom += aLire.readChar();
} catch ( EOFException e ) {
finFichier = true;
}
if (!finFichier) {
int gold=aLire.readInt(),
silver=aLire.readInt(),
bronze=aLire.readInt(),
sum=aLire.readInt();
Pays pers = new Pays(nom, gold, silver, bronze, sum);
unVect.add(pers);
}
}
aLire.close();
return unVect;
}
public static void main(String[]args)throws IOException
{
LinkedList<Pays> liste = lireCreer("Olym_ete.txt");
System.out.println("");
System.out.println("1)Determine et afficher les 5 premier pays qui ont gagne plus de medailles en totale: ");
quickSort(liste,0, liste.size()-1);
afficher(liste,5);
System.out.println("");
System.out.println("2)Afficher les information des pays FRANCE, JAPON, ESPAGNE: ");
afficherPays(liste,"FRANCE");
afficherPays(liste,"JAPON");
afficherPays(liste,"ESPAGNE");
System.out.println("");
System.out.println("3)Cree a partir de la liste un fichier binaire qui ont gagne au moins de 5 medailles en or: ");
creerBinaire(liste, 5,"AtLeastFiveGold.bin");
LinkedList<Pays> plusKeFive = readBinaire("AtLeastFiveGold.bin");
System.out.println(plusKeFive.size());
System.out.printf("%30s %10d %10d %10d %10d\n",plusKeFive.get(1).getNom(),plusKeFive.get(1).getGold(),plusKeFive.get(1).getSilver(),plusKeFive.get(1).getBronze(),plusKeFive.get(1).getSum());
}
}
I can't figure out how to get rid of the symbols. I suspect that i have made a mistake while reading the binary file in readBinaire() but i cannot seem to figure out where i went wrong.

A char in Java is a 16-bit Unicode character. A "byte" is an 8-bit byte.
You're using writeBytes to write a string as 38 bytes, but readChar to read them back in as 19 characters. writeBytes will write the low order 8 bits of each 16-bit character of the string. So if your string was "ABCD", the bytes it would write are
0x41 0x42 0x43 0x44
Then when you read them back in as 16-bit characters, it will read the first two characters either as
0x4142 0x4344
or
0x4241 0x4443
depending on how the byte ordering is handled. Either way, instead of "ABCD", you will get some strange Unicode characters whose code points are U+4142 or U+4241, and U+4344 or U+4443. (They are probably not displaying correctly.)

Related

java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 7 on a binary search

I have to write a program for search the correspondent of "Nomi" by entering the "Prezzo" value, but when I do the binary search, I get the error:
java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 7 on a binary search
Here is the code:
import java.io.*;
public class Blackfriday {
public static int ricercaBinaria(Double prezzi[], Double chiave) {
int inf = 0, sup = prezzi.length - 1;
while (inf <= sup) {
int med = (inf + sup) / 2;
if (prezzi[med] == chiave)
return med;
if (prezzi[med] < chiave)
inf = med + 1;
else
sup = med - 1;
}
return -1;
}
public static void main(String args[]) {
try {
InputStreamReader isr;
BufferedReader br;
double cerca;
isr = new InputStreamReader(System.in);// abilitato la lettura da tastiera
br = new BufferedReader(isr);// abilitato la lettura un rigo per volta
String nomi[] = { "picones", "vinile di Speranza", "Laurea", "King Mufasa", "Pentium Gold",
"Aethey Wind breaker ORO", "HeelCompletoSpaic1we" };
Double prezzi[] = { 2.0, 13.50, 23.0, 99.50, 120.0, 75.20, 999.99 };
System.out.println("Quanto vuoi spendere?");
String xStringa = br.readLine();// ricevo la digitazione in String
cerca = Double.parseDouble(xStringa);// Trasformo la String in double
System.out.println("Puoi comprare: " + nomi[ricercaBinaria(prezzi, cerca)]);
} catch (Exception e) {
System.out.println(e);
}
}
}
Here is a functioning code :
Always display the stackTrace in case of Exception catch, it will help for the debug
if you manage Objects "Double" and try to compare them with ==, it will compare their reference (address in memory) and not the value contained inside of them. So use simple type double OR compare objects with equals() method.
public class Blackfriday {
public static int ricercaBinaria(double prezzi[], Double chiave) {
int inf = 0, sup = prezzi.length - 1;
while (inf <= sup) {
int med = (inf + sup) / 2;
if (prezzi[med] == chiave)
return med;
if (prezzi[med] < chiave)
inf = med + 1;
else
sup = med - 1;
}
return -1;
}
public static void main(String args[]) {
try {
InputStreamReader isr;
BufferedReader br;
double cerca;
isr = new InputStreamReader(System.in);//abilitato la lettura da tastiera
br = new BufferedReader(isr);//abilitato la lettura un rigo per volta
String nomi[] = {"picones", "vinile di Speranza", "Laurea", "King Mufasa", "Pentium Gold", "Aethey Wind breaker ORO", "HeelCompletoSpaic1we"};
double prezzi[] = {2.0, 13.50, 23.0, 99.50, 120.0, 75.20, 999.99};
System.out.println("Quanto vuoi spendere?");
String xStringa = br.readLine();//ricevo la digitazione in String
cerca = Double.parseDouble(xStringa);//Trasformo la String in double
System.out.println("Puoi comprare: " + nomi[ricercaBinaria(prezzi, cerca)]);
} catch (Exception e) {
e.printStackTrace();
}
}//main
}//classe
There are at least two problems with your code.
A precondition of ricercaBinaria is that the underlying data array is ordered. You are using unordered data in your test
ricercaBinaria will return the index in which a given argument (Double) is located in your array. If it is not found, then -1 will be returned. As such, you need to check the returned index to verify that it is indeed positive before using it as an index array - otherwise the method will fail with the exception you are seeing
Beware of Double equality but that is for another question.

How to binary search for a specific year in an array of objects containing a specific year

I'm trying to get the code to search for a songs that were made in a specific year
I've tried implementing my own binary search code but it's not working and instead asks for an input when I never asked for an input
Class:
public class MusicV3
{
// instance variables
private int year;
private String title;
private String artist;
// Constructor for objects of class Music
public MusicV3(String t, int y, String a)
{
// initialize instance variables
title = t;
year = y;
artist = a;
}
public String getTitle()
{
return title;
}
public void setTitle(String t)
{
title = t;
}
public String getArtist()
{
return artist;
}
public void setArtist(String a)
{
artist = a;
}
public int getYear()
{
return year;
}
public void setTitle(int y)
{
year = y;
}
public String toString()
{
String str = String.format( "%-25s %4d %-20s ", title, year , artist);
return str;
}
}
Tester class:
public class MusicV3Tester
{
public static void main(String[]args)
{
int find = 0;
MusicV3[] songs = new MusicV3[10];
MusicV3[] sortedSongs = new MusicV3[songs.length];
songs[0] = new MusicV3("Sugar", 2014, "Maroon 5");
songs[1] = new MusicV3("Mercy", 2016, "Shawn Mendes");
songs[2] = new MusicV3("Shape of You", 2017, "Ed Sheeran");
songs[3] = new MusicV3("Photograph", 2014, "Ed Sheeran");
songs[4] = new MusicV3("Closer", 2016, "The Chainsmokers");
songs[5] = new MusicV3("Galway Girl", 2017, "Ed Sheeran");
songs[6] = new MusicV3("Counting Stars", 2013, "OneRepublic");
songs[7] = new MusicV3("7 Years", 2015, "Lukas Graham");
songs[8] = new MusicV3("Night Changes", 2014, "One Direction");
songs[9] = new MusicV3("What Makes You Beautiful", 2011, "One Direction");
printSongs(songs);
System.out.println();
sortedSongs = sortBySong(songs);
System.out.println("Song list sorted by songs:");
//printSongs(sortedSongs);
System.out.println();
System.out.println("Searching for the song: Paris");
find = findSong(songs, "Paris");
if(find != -1){
System.out.println("We found Paris in the song list: ");
System.out.println(sortedSongs[find]);
}
else
System.out.println("Paris is not in the song list");
System.out.println();
System.out.println("Searching for the song: Sugar");
find = findSong(songs, "Sugar");
if(find != -1){
System.out.println("We found Sugar in the song list: ");
System.out.println(sortedSongs[find]);
}
else
System.out.println("Sugar is not in the song list");
System.out.println();
sortedSongs = sortByYear(songs);
System.out.println("Song list sorted by year:");
//printSongs(sortedSongs);
System.out.println();
System.out.println("Searching for the year: 2000");
find = findYear(songs, 2000);
if(find != -1){
System.out.println("We found songs made in the year 2000 in the song list: ");
System.out.println(sortedSongs[find]);
}
else
System.out.println("Songs made in the year 2000 are not in the song list");
System.out.println();
System.out.println("Searching for the year: 2014");
findYear(songs, 2014);
if(find != -1){
System.out.println("We found songs made in the year 2014 in the song list: ");
System.out.println(sortedSongs[find]);
}
else
System.out.println("Songs made in the year 2014 are not in the song list");
System.out.println();
sortedSongs = sortByArtist(songs);
System.out.println("Song list sorted by artist:");
//printSongs(sortedSongs);
System.out.println();
System.out.println("Searching for the artist: Sia");
findArtist(songs, "Sia");
System.out.println();
System.out.println("Searching for the artist: Ed Sheeran");
findArtist(songs, "Ed Sheeran");
System.out.println();
}
public static void printSongs(MusicV3[] s)
{
System.out.println("Song Year Artist");
System.out.println("-------------------------------------------------------");
for(int i = 0; i < s.length; i++)
System.out.println(s[i]);
}
public static MusicV3[] sortBySong(MusicV3 [] songs){
MusicV3[] sortedList = songs;
int i;
int k;
int posmax;
MusicV3 temp;
for ( i = songs.length - 1 ; i >= 0 ; i-- )
{
posmax = 0;
for ( k = 0 ; k <= i ; k++ )
{
if (songs[k].getTitle().compareTo(songs[posmax].getTitle()) > 0)
posmax = k;
}
temp = songs[i];
songs[i] = songs[posmax];
songs[posmax] = temp;
}
return sortedList;
}
public static MusicV3[] sortByYear(MusicV3 [] movies){
MusicV3[] sortedList = movies;
int i;
int k;
int posmax;
MusicV3 temp;
for ( i = movies.length - 1 ; i >= 0 ; i-- )
{
posmax = 0;
for ( k = 0 ; k <= i ; k++ )
{
if (movies[k].getYear()> movies[posmax].getYear())
posmax = k;
}
temp = movies[i];
movies[i] = movies[posmax];
movies[posmax] = temp;
}
return sortedList;
}
public static MusicV3[] sortByArtist(MusicV3 [] songs){
MusicV3[] sortedList = songs;
int i;
int k;
int posmax;
MusicV3 temp;
for ( i = songs.length - 1 ; i >= 0 ; i-- )
{
posmax = 0;
for ( k = 0 ; k <= i ; k++ )
{
if (songs[k].getArtist().compareTo(songs[posmax].getArtist()) > 0)
posmax = k;
}
temp = songs[i];
songs[i] = songs[posmax];
songs[posmax] = temp;
}
return sortedList;
}
public static int findSong( MusicV3[] songs, String song){
int high = songs.length;
int low = -1;
int probe;
while ( high - low > 1 )
{
probe = ( high + low ) / 2;
if (songs[probe].getTitle().compareTo(song) > 0)
high = probe;
else
low = probe;
}
if ( low >= 0 && songs[low].getTitle().compareTo(song) == 0){
return low;
}
else{
return -1;
}
}
public static int findYear(MusicV3[] songs, int year){
int high = songs.length - 1;
int low = 0;
int probe;
while (low <= high)
{
probe = ( high + low ) / 2;
if (songs[probe].getYear() == year)
return probe;
if(songs[probe].getYear() > year)
low = probe;
else
low = probe + 1;
}
return -1;
}
public static void findArtist(MusicV3[] s, String artist)
{
int found = 0;
for(int i = 0; i < s.length; i++){
if (s[i].getArtist().compareTo(artist) == 0)
{
System.out.println(s[i]);
found++;
}
}
if (found == 0)
{ // we have not found the location
System.out.println("There are no songs on the songs list made in the year " + artist);
System.out.println();
}
else
{
System.out.print("There were " + found + " listings for " + artist);
System.out.println();
}
}
}
Ignore the song and artist search, those I can do and have no problems with but with the year search, it's not working correctly since it is supposed to correctly print all of the songs that are in the specific year giving (2000 and 2014) but it isn't and instead is not working at all and asking for an input for some reason. This is my first time doing a binary search so i'm pretty new to this.
How can you possibly show all of them when you are only returning the index of one of them (and not even the first one at that) ?
Try returning a list of results. or a Pair<int, int> of indexes begin and end

Method returns wrong value in main class

Whenever I run InschrijvingApplicatie, I get a wrong value out of line System.out.printf("Hoeveel broodjes wil je bestellen? (max %d) ", maxBroodjes); because the int should be "10" when I enter 'p' in this line
System.out.printf("Tot welke categorie behoort u?\nTyp w voor een werknemer, p voor een werknemer met partner, g voor een gast: ");
I'm supposing there is something wrong at the line int maxBroodjes = (inschrijving.geefAantalPersonen() * 5); but can't seem to figure out what.
How the output should look like
The excercise is: for a company that is inviting employees ('w' in the code), employee with a partner ('p') and guests ('g') and letting them fill in their name, what sort of visitor (employee + partner, guest or employee) they are, then asking how many sandwiches the person wants (guest and employee can max require 5 sandwiches, employee+partner can request 10) and the max value is shown in the integer (max %d). All of this is in a loop until the user writes "no" (but the first char is used => resulting in 'n') when asked "Zijn er nog inschrijvingen", and if the answer is yes, it repeats.
Inschrijving.java
package domein;
public class Inschrijving {
private String naam;
private char categorie;
private int aantalBroodjes;
public Inschrijving(String naam, char categorie) {
setNaam(naam);
setCategorie(categorie);
}
public String getNaam() {
return naam;
}
private void setNaam(String naam) {
this.naam = naam;
}
public char getCategorie() {
return categorie;
}
private void setCategorie(char categorie) {
if (categorie == 'w' || categorie == 'p' || categorie == 'g') {
this.categorie = categorie;
} else {
this.categorie = 'g';
}
}
public int getAantalBroodjes() {
return aantalBroodjes;
}
public void setAantalBroodjes(int aantalBroodjes) {
if (aantalBroodjes <= (geefAantalPersonen() * 5)) {
this.aantalBroodjes += aantalBroodjes;
} else {
this.aantalBroodjes += (geefAantalPersonen() * 2);
}
}
public int geefAantalPersonen() {
switch (categorie) {
case 'w':
case 'g':
return 1;
default:
return 2;
}
}
}
InschrijvingApplicatie
package ui;
import domein.Inschrijving;
import java.util.Scanner;
public class InschrijvingApplicatie {
public static void main(String[] args) {
Scanner invoer = new Scanner(System.in);
String antwoord;
char eersteLetter;
System.out.println("Zijn er nog inschrijvingen? ");
antwoord = invoer.nextLine();
eersteLetter = antwoord.toLowerCase().charAt(0);
String naam = null;
String categorie;
char categorieEersteLetter = 0;
int werknemer = 0;
int werknemerMetPartner = 0;
int gast = 0;
int aantalBroodjes;
int tijdelijk;
Inschrijving inschrijving = new Inschrijving(naam, categorieEersteLetter);
if (eersteLetter != 'n') {
do {
System.out.println("Wie mag ik inschrijven? ");
naam = invoer.next();
do {
System.out.printf("Tot welke categorie behoort u?\nTyp w voor een werknemer, p voor een werknemer met partner, g voor een gast: ");
categorie = invoer.next();
categorieEersteLetter = categorie.toLowerCase().charAt(0);
switch (categorieEersteLetter) {
case 'w':
werknemer++;
break;
case 'p':
werknemerMetPartner++;
break;
case 'g':
gast++;
break;
}
} while (categorieEersteLetter != 'w' && categorieEersteLetter != 'p' && categorieEersteLetter != 'g');
int maxBroodjes = (inschrijving.geefAantalPersonen() * 5);
do {
System.out.printf("Hoeveel broodjes wil je bestellen? (max %d) ", maxBroodjes);
tijdelijk = invoer.nextInt();
} while (tijdelijk > maxBroodjes);
aantalBroodjes = tijdelijk;
inschrijving.setAantalBroodjes(aantalBroodjes);
System.out.println("Zijn er nog inschrijvingen? ");
antwoord = invoer.next();
eersteLetter = antwoord.toLowerCase().charAt(0);
} while (eersteLetter != 'n');
}
System.out.printf("Er komen %d werknemer(s) zonder partner, %d werknemer(s) met partner en %d gast(en) naar de receptie. Er dienen %d broodjes besteld te worden.", werknemer, werknemerMetPartner, gast, inschrijving.getAantalBroodjes());
}
}
There are some problems with your approach, it may work but you shouldn't do that way.
First, you store the total sandwiches requested for all invited peopled in only one Inschrijving object, it make no sense! (Do I need to know the total sandwiches requested or only ones requested by me?). So, change setAantalBroodjes in your Inschrijving class to :
public void setAantalBroodjes(int aantalBroodjes) {
this.aantalBroodjes = aantalBroodjes;
}
Second, The requirement is take a list of people and do something with them, so you should consider use a data structure support you store a list of people like an Array or an ArrayList, then you can do whatever you want with your data once user stop input (eersteLetter == 'n' in your case).
List<Inschrijving> inschrijven = new ArrayList<>();
try (Scanner invoer = new Scanner(System.in)) { // http://tutorials.jenkov.com/java-exception-handling/try-with-resources.html
System.out.println("Zijn er nog inschrijvingen? ");
String antwoord = invoer.nextLine();
char eersteLetter = antwoord.toLowerCase().charAt(0);
while (eersteLetter != 'n') {
Inschrijving inschrijving = null;
System.out.println("Wie mag ik inschrijven? ");
String naam = invoer.nextLine();
char categorieEersteLetter = 0;
do {
System.out.printf(
"Tot welke categorie behoort u?\nTyp w voor een werknemer, p voor een werknemer met partner, g voor een gast: ");
String categorie = invoer.nextLine();
categorieEersteLetter = categorie.toLowerCase().charAt(0);
} while (categorieEersteLetter != 'w' && categorieEersteLetter != 'p' && categorieEersteLetter != 'g');
inschrijving = new Inschrijving(naam, categorieEersteLetter);
int maxBroodjes = (inschrijving.geefAantalPersonen() * 5);
int tijdelijk;
do {
System.out.printf("Hoeveel broodjes wil je bestellen? (max %d) ", maxBroodjes);
tijdelijk = invoer.nextInt();
invoer.nextLine(); // https://stackoverflow.com/questions/13102045/scanner-is-skipping-nextline-after-using-next-or-nextfoo
} while (tijdelijk > maxBroodjes);
inschrijving.setAantalBroodjes(tijdelijk);
inschrijven.add(inschrijving);
System.out.println("Zijn er nog inschrijvingen? ");
antwoord = invoer.nextLine();
eersteLetter = antwoord.toLowerCase().charAt(0);
}
}
When the user finished their input:
// Do stuffs with your list of people here
int werknemer = 0;
int werknemerMetPartner = 0;
int gast = 0;
int aantalBroodjes = 0;
for (Inschrijving inschrijving : inschrijven) {
char categorie = inschrijving.getCategorie();
switch (categorie) {
case 'w':
werknemer++;
break;
case 'p':
werknemerMetPartner++;
break;
case 'g':
gast++;
break;
}
aantalBroodjes += inschrijving.getAantalBroodjes();
}
System.out.printf(
"Er komen %d werknemer(s) zonder partner, %d werknemer(s) met partner en %d gast(en) naar de receptie. Er dienen %d broodjes besteld te worden.",
werknemer, werknemerMetPartner, gast, aantalBroodjes);
Because you are new to java, I use a foreach loop here to make example, after learning about OOP and familiar with java, I suggest you reaserch Java 8 Stream api and lambda expression to work with collection types.

My own Exception doesn't work

I wrote a program who simulate a card game.
I choose some values for the colors of the card and some values for values of the cards.
I wrote my own Exception, is CarteException.java who have two child, CarteValeurException.java and CarteCouleurException.java depending on the type of Exception at the initialisation of a Carte
If the value of the color is not in 1 or 4, that will be throw an Exception of CarteCouleurExeception.java and same for the other Exception, if the value are not 1 or in 7 and 13, that will be throw a CarteValeurException.java
This is my code for the class Carte.java :
public Carte(int coul, int val) throws CarteException {
if(coul < 1 || coul > 4) {
throw new CarteCouleurException("Erreur d'initialisation lors de la création d'une carte.",coul);
}
if(val < 1 || (val > 1 && val < 7) || val > 13) {
throw new CarteValeurException("Erreur d'initialisation lors de la création d'une carte.",val);
}
this.couleur = coul;
this.valeur = val;
}
This is the code for the Class CarteException.java :
public class CarteException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
protected String message;
protected CarteException() {
this.message = "";
}
public CarteException(String chaine) {
this.message = chaine;
}
public String getMessage() {
return (this.message + " : Erreur non spécifiée de valeur ou de couleur de carte.");
}
}
And finally, the initialisation of a card in Belote.java :
package TP.TP6.Exercice2;
import java.util.Random;
import java.util.Vector;
import java.util.Stack;
import TP.TP5.Exercice1.Question4.Carte;
public class Belote {
private Stack<Carte> tasDistibution;
private Vector<Stack<Carte>> mainsJoueurs;
private Vector<Stack<Carte>> plisJoueurs;
public Belote() {
this.tasDistibution = new Stack<Carte>();
this.mainsJoueurs = new Vector<Stack<Carte>>(4);
this.plisJoueurs = new Vector<Stack<Carte>>(4);
for(int i = 0 ; i < 4 ; i++) {
this.mainsJoueurs.add(i, new Stack<Carte>());
this.plisJoueurs.add(i, new Stack<Carte>());
}
}
private void initialiserTasDistribution() throws CarteException {
for (int i = 0; i <= 5; i++) {
for (int j = 1; j <= 13; j++) {
try {
//Initialisation right here
this.tasDistibution.push(new Carte(i,j));
}
catch(CarteException CE) {
System.err.println("Erreur : " + CE);
}
}
}
}
private void couper() {
Stack<Carte> tas1 = new Stack<Carte>();
Stack<Carte> tas2 = new Stack<Carte>();
Random r = new Random();
int coupe = 1 + r.nextInt(33 - 1);
for (int i = 0; i < coupe; i++) {
Carte carte = this.tasDistibution.peek();
this.tasDistibution.pop();
tas1.push(carte);
}
while (tasDistibution.isEmpty() == false) {
Carte carte = this.tasDistibution.peek();
this.tasDistibution.pop();
tas2.push(carte);
}
while (tas1.isEmpty() == false) {
Carte carte = tas1.peek();
tas1.pop();
this.tasDistibution.push(carte);
}
while (tas2.isEmpty() == false) {
Carte carte = tas2.peek();
tas2.pop();
this.tasDistibution.push(carte);
}
}
private void melanger(int nbMelange) {
Carte tabcarte[] = new Carte[32];
for (int i = 0; i < tabcarte.length; i++) {
Carte cartesommet = this.tasDistibution.peek();
this.tasDistibution.pop();
tabcarte[i] = cartesommet;
}
for (int i = 0; i < nbMelange; i++) {
Random r = new Random();
int pos1 = 1 + r.nextInt(32 - 1);
int pos2 = 1 + r.nextInt(32 - 1);
if (pos1 == pos2) {
System.out.println("Pas de chance");
} else {
Carte temp;
temp = tabcarte[pos1];
tabcarte[pos1] = tabcarte[pos2];
tabcarte[pos2] = temp;
}
}
for (int i = 0; i < tabcarte.length; i++) {
Carte carte = tabcarte[i];
this.tasDistibution.push(carte);
}
}
private void donnerCartesAJoueur(int nbcartedonnes, int numjoueur) {
for (int i = 0; i < nbcartedonnes; i++) {
Carte carte = this.tasDistibution.peek();
this.tasDistibution.pop();
Stack<Carte> stack = this.mainsJoueurs.get(numjoueur);
stack.push(carte);
this.mainsJoueurs.set(numjoueur, stack);
}
}
private void distribuer() {
for (int i = 0; i < 4; i++) {
this.donnerCartesAJoueur(3, i);
}
for (int i = 0; i < 4; i++) {
this.donnerCartesAJoueur(2, i);
}
for (int i = 0; i < 4; i++) {
this.donnerCartesAJoueur(3, i);
}
for (int i = 0; i < 4; i++) {
System.out.println("\n\nDistribution pour joueur : " + (i+1) + " \n\nMain du joueur : " + (i+1));
System.out.println(this.mainsJoueurs.get(i).toString());
}
}
private void assemblerPlisJoueur() {
for (int i = 0; i < 4; i++) {
while (this.plisJoueurs.get(i).isEmpty() == false) {
Carte carte = this.plisJoueurs.get(i).peek();
Stack<Carte> stack = this.plisJoueurs.get(i);
stack.pop();
this.plisJoueurs.set(i, stack);
this.tasDistibution.push(carte);
}
}
}
private void preparerPremiereManche() throws CarteException {
try {
this.initialiserTasDistribution();
}
catch(CarteException CE) {
System.err.println("Erreur d'initilisation du tas à distribuer.");
throw CE;
}
this.melanger(32);
this.couper();
this.distribuer();
}
private void preparerMancheSuivante() {
this.assemblerPlisJoueur();
this.couper();
this.distribuer();
}
private void jouerPli() {
Stack<Carte> tasIntermediaire = new Stack<Carte>();
for (int i = 0; i < 4; i++) {
Carte carte = this.mainsJoueurs.get(i).peek();
Stack<Carte> stack = this.mainsJoueurs.get(i);
stack.pop();
this.mainsJoueurs.set(i, stack);
tasIntermediaire.push(carte);
}
Random r = new Random();
int gagnant = 0 + r.nextInt(4 - 0);
System.out.println("Le joueur " + (gagnant+1) + " a gagné ce pli");
for (int i = 0; i < 4; i++) {
Carte carte = tasIntermediaire.peek();
tasIntermediaire.pop();
Stack<Carte> stack = this.plisJoueurs.get(gagnant);
stack.push(carte);
this.plisJoueurs.set(gagnant, stack);
}
System.out.println("Pli du joueur " + (gagnant+1));
System.out.println(this.plisJoueurs.get(gagnant).toString());
}
private void jouerManche(int nbPlis) {
for (int i = 1; i <= nbPlis; i++) {
System.out.println("\n\nPli numéro : " + i);
this.jouerPli();
}
this.preparerMancheSuivante();
}
public void jouerPartie(int nbManches) throws CarteException {
try {
this.preparerPremiereManche();
}
catch(CarteException CE) {
System.err.println("Erreur d'initialisation de la première manche");
throw CE;
}
for (int i = 1; i <= nbManches; i++) {
System.out.println("\n\nManche numéro : " + i);
this.jouerManche(8);
}
System.out.println("Jeu terminé");
}
}
The problem is in Belote.java, Eclipse send me an error like this here catch(CarteException CE) :
Unreachable catch block for CarteException. This exception is never thrown from the try statement body
But i put right : public Carte(int coul, int val) throws CarteException in the first class so don't understand the problem.
I wrote the class CarteValeurException.java and CarteCouleurException.java but that is practically the same than CarteException.java so that's why i don't put the code of the class right here.
Thank you for your help !
You have to throw or catch your exception.
The signature of your method is:
private void initialiserTasDistribution() throws CarteException
So when the exception is trowed from the constructor in Carte is re-throwed by your method. Thus the catch is unreachable. You have to chose the best approach for your code.
Here a set of rules of thumb: Throws or try+catch
Your problem is that your method is declared to propagate the exception higher up the call stack:
private void initialiserTasDistribution() throws CarteException {
This means that whoever calls the method initialiserTasDistribution will have to handle this exception instead (or do the same and propagate it even higher). It is a form of deferring responsibility. It's saying "I'm not going to handle this error, someone else can".
This directly contradicts the implementation of your method because you do in fact handle the error.
try {
this.tasDistibution.push(new Carte(i,j));
}
catch(CarteException CE) {
System.err.println("Erreur : " + CE);
}
If you change your method signature to remove the throws declaration, you should be okay:
private void initialiserTasDistribution() {

ClassCastException String cannot be converted to custom class

This ClassCastException is driving me crazy.
When invoking the method insert() I get this:
Exception in thread "main" java.lang.ClassCastException:
java.lang.String cannot be cast to Rubrica$Pair
Hope anybody can help without loosing much time :).
class Rubrica implements Dictionary
{
private Object[] v;
private int vSize;
public static int INITSIZE = 1;
/*
verifica se il dizionario contiene almeno una coppia chiave/valore
*/
public Rubrica()
{
v = new Object[INITSIZE];
makeEmpty();
}
private Object[] resize(Object[] v, int length)
{
Object[] newv = new Object[length * 2];
System.arraycopy(v, 0, newv, 0, length);
return newv;
}
/*
svuota il dizionario
*/
public void makeEmpty()
{
for(int i = 0; i < v.length; i++)
v[i] = new Pair(null, -1);
vSize = 0;
}
/*
Inserisce un elemento nel dizionario. L'inserimento va sempre a buon fine.
Se la chiave non esiste la coppia key/value viene aggiunta al dizionario;
se la chiave esiste gia' il valore ad essa associato viene sovrascritto
con il nuovo valore; se key e` null viene lanciata IllegalArgumentException
*/
private Object[] insertionSort(Object[] v, int vSize)
{
for(int i = 0; i < vSize; i++)
{
Comparable temp = ((Pair)v[i]).getName();
int j;
for(j = i; j > 0 && temp.compareTo(((Pair)v[j - 1]).getName()) < 0; j--)
v[j] = v[j - 1];
v[j] = temp;
}
return v;
}
public void insert(Comparable key, Object value)
{
if(vSize == v.length)
v = resize(v, vSize);
if(key.equals(null))
throw new IllegalArgumentException();
int index = binaryKeyIndexSearch(v, vSize, key);
if(index == -1)
v[vSize++] = new Pair((String)key, (long)value);
else
v[index] = new Pair((String) key, (long)value);
v = insertionSort(v, vSize);
}
/*
Cerca nel dizionario l'elemento specificato dalla chiave key
La ricerca per chiave restituisce soltanto il valore ad essa associato
Se la chiave non esiste viene lanciata DictionaryItemNotFoundException
*/
private int binaryKeyIndexSearch(Object[] v, int vSize, Comparable value)
{
return binKeySearch(v, 0, vSize - 1, value);
}
private int binKeySearch(Object[] v, int from, int to, Comparable value)
{
if(from > to)
return -1;
int mid = (from + to) / 2;
Comparable midValue = ((Pair)v[mid]).getName(); //errore
if(value.compareTo(midValue) == 0)
return mid;
else if(value.compareTo(midValue) < 0)
return binKeySearch(v, from, mid - 1, value);
else
return binKeySearch(v, mid + 1, to, value);
}
//classe privata Pair: DO NOT MODIFY!!
private class Pair
{ public Pair(String aName, long aPhone)
{ name= aName;
phone = aPhone;
}
public String getName()
{ return name; }
public long getPhone()
{ return phone; }
/*
Restituisce una stringa contenente
- la nome, "name"
- un carattere di separazione ( : )
- il numero telefonico, "phone"
*/
public String toString()
{ return name + " : " + phone; }
//campi di esemplare
private String name;
private long phone;
}
}
The problem is in this method:
private Object[] insertionSort(Object[] v, int vSize)
{
for(int i = 0; i < vSize; i++)
{
Comparable temp = ((Pair)v[i]).getName();
int j;
for(j = i; j > 0 && temp.compareTo(((Pair)v[j - 1]).getName()) < 0; j--)
v[j] = v[j - 1];
v[j] = temp;
}
return v;
}
Look closely, you write to temp the name of v[i] and then assign temp to v[j]so now you have String instead of Pair in v[j].
You could get rid of ClassCastExceptions if you have used the correct type for your array, which is Pair[]. I mean if you swap all Object[] to Pair[] you will see this kind of incorrect assignment in compile time, not in runtime.

Categories