Java kleines Problem

bra-tak

Lt. Junior Grade
Registriert
Apr. 2009
Beiträge
450
Hallo,

ich habe ein Problem, und zwar gibt mir mein folgender Code - egal was man eingibt - null als Skalarprodukt aus.

Kann sich das einer mal anschauen, ist sicher nur ein kleiner fehler, aber ich scheine ihn zu übersehen :)

Danke schonmal!

Code:
public class Hallo {
	static int dim;
	
	public static int Vlesen(int[] x, int[] y) {
		SimpleIO.println("Hallo liebe JAVA-Welt! " +
				"Dies ist ein Programm zur Berechnung von Längen, Skalarprodukten, Kreuzprodukten und Summen von Vektoren");
		SimpleIO.println("Geben Sie bitte ein, wie viele Dimensionen der Raume der Vektoren umfasst!");
		SimpleIO.println("");
		
		dim=SimpleIO.readInteger();
		
		x=new int [dim];
		y=new int [dim];
		boolean againV1;
		boolean againV2;
		
		//Vektor 1 einlesen
		
		do {
			try {
				SimpleIO.println("Bitte alle Komponenten von Vektor1 mit 'Enter' getrennt eingeben!");
				
				for (int i=0;i<dim;i++) {
					x[i]=SimpleIO.readInteger();
				}
				againV1=false;
				
			} catch (NullPointerException e) {
				SimpleIO.println("ACHTUNG!!!");
				SimpleIO.println("Die Eingabe muss eine Zahl ohne Komma oder Punkt sein !!! (int) ");
				SimpleIO.println("");
				againV1=true;
			}
		} while (againV1);
		
		//Vektor 2 einlesen
		
		do {
			try {
				SimpleIO.println("Bitte alle Komponenten von Vektor2 mit 'Enter' getrennt eingeben!");
				
				for (int i=0;i<dim;i++) {
					y[i]=SimpleIO.readInteger();
				}
				againV2=false;
				
			} catch (NullPointerException e) {
				SimpleIO.println("ACHTUNG!!!");
				SimpleIO.println("Die Eingabe muss eine Zahl ohne Komma oder Punkt sein !!! (int) ");
				SimpleIO.println("");
				againV2=true;
			}
			
		} while (againV2);
		
		//Vektoren an den Benutzer ausgeben
		
		SimpleIO.println("Es werden Berechnungen auf Grundlage der folgenden beiden Vektoren durchgeführt:");
		SimpleIO.println("");
		
		for (int i=0;i<dim;i++) {
			SimpleIO.println("      " + x[i] + "           " + y[i]);
		}
		
		return 0;
	}
	public static int SProdukt(int[] c, int[] d) {
		c=new int [dim];
		d=new int [dim];
		int skalarP=0;
		
		for (int i=0;i<dim;i++) {
			skalarP+=c[i]*d[i];
		}
		
		SimpleIO.println("");
		SimpleIO.println("Das Skalarprodukt der Vektoren beträgt:  " + skalarP + "  !");
		SimpleIO.println("");
		return 0;
	}
	
	
	public static void main (String[] args) {
		int[] a,b;
		a=new int [dim];
		b=new int [dim];
		Vlesen(a,b);
		SProdukt(a,b);
	}
}
 
Wieso werden in der VLesen Methode die Variable neu zugewiesen? Also:
Code:
x=new int [dim];
y=new int [dim];
Ebenso in der SProdukt Methode.

EDIT: Wobei in der VLesen Methode muss es sein, da ja die dim Variable vorher nicht gesetzt wurde. Aus main kannste es aber auch entfernen.
 
Da stimmt gleich mehreres nicht.

public static int SProdukt(int[] c, int[] d) {
c=new int [dim];
d=new int [dim];

int skalarP=0;

for (int i=0;i<dim;i++) {
skalarP+=c*d;
}

SimpleIO.println("");
SimpleIO.println("Das Skalarprodukt der Vektoren beträgt: " + skalarP + " !");
SimpleIO.println("");
return 0;
}


Du willst in der Funktion ja die übergebenen c und d verwenden. Da solltest du sie nicht überschreiben.

Ich nehme auch an, dass du nicht 0 als Rückgabewert haben möchtest, sondern skalarP.
 
weil ich so verwechslungen meinerseits beim proggen erstmal umgehe. das kann ja immernoch gefixt werden. nur darum geht es mir ja überhaupt nicht... :(
 
Wenn du in jeder Methode die Arrays neu erstellst, behalten sie aber ihren Inhalt nicht.
 
DjNDB schrieb:
Da stimmt gleich mehreres nicht.



Du willst in der Funktion ja die übergebenen c und d verwenden. Da solltest du sie nicht überschreiben.

Ich nehme auch an, dass du nicht 0 als Rückgabewert haben möchtest, sondern skalarP.

hey,

c und d werden ja auch wie gewollt verwendet. die sind doch nur zur übergabe an die main vorhanden. und ich will auch nichts in den return schreiben, da ich doch über mein SimpleIO.println mein ergebnis sofort an den benutzer ausgeben möchte.

an sich funzt ja alles vom algorithmus her, nur wenn ich in dem teil

Code:
int skalarP=0;
		
		for (int i=0;i<dim;i++) {
			skalarP+=c[i]*d[i];
		}

zum beispiel statt =0 vier hinschreibe, dann sagt mir die ausgabe dass das Skalarprodukt vier ist. er rechnet gar nicht, sondern gibt mir das initialisierte aus. warum? warum wird die for-Schleife nicht beachtet?
 
bra-tak schrieb:
hey,

c und d werden ja auch wie gewollt verwendet. die sind doch nur zur übergabe an die main vorhanden. und ich will auch nichts in den return schreiben, da ich doch über mein SimpleIO.println mein ergebnis sofort an den benutzer ausgeben möchte.

an sich funzt ja alles vom algorithmus her, nur wenn ich in dem teil

Code:
int skalarP=0;
		
		for (int i=0;i<dim;i++) {
			skalarP+=c[i]*d[i];
		}

zum beispiel statt =0 vier hinschreibe, dann sagt mir die ausgabe dass das Skalarprodukt vier ist. er rechnet gar nicht, sondern gibt mir das initialisierte aus. warum? warum wird die for-Schleife nicht beachtet?

Wenn du nichts zurückgeben möchtest, kannst du auch void in der methodensignatur verwenden....

Die For schleife wird ausgeführt, aber da die Arrays, dadurch dass du sie neu initialisierst, nur noch nullen enthalten, und du somit immer wieder 0 addierst, verändert skalarP seinen wert nicht.
 
cx01 schrieb:
Wenn du in jeder Methode die Arrays neu erstellst, behalten sie aber ihren Inhalt nicht.

wenn ich das so mache

Code:
public class Hallo {
	static int dim;
	
	public static int Vlesen(int[] x, int[] y) {
		SimpleIO.println("Hallo liebe JAVA-Welt! " +
				"Dies ist ein Programm zur Berechnung von Längen, Skalarprodukten, Kreuzprodukten und Summen von Vektoren");
		SimpleIO.println("Geben Sie bitte ein, wie viele Dimensionen der Raume der Vektoren umfasst!");
		SimpleIO.println("");
		
		dim=SimpleIO.readInteger();
		
		x=new int [dim];
		y=new int [dim];
		boolean againV1;
		boolean againV2;
		
		//Vektor 1 einlesen
		
		do {
			try {
				SimpleIO.println("Bitte alle Komponenten von Vektor1 mit 'Enter' getrennt eingeben!");
				
				for (int i=0;i<dim;i++) {
					x[i]=SimpleIO.readInteger();
				}
				againV1=false;
				
			} catch (NullPointerException e) {
				SimpleIO.println("ACHTUNG!!!");
				SimpleIO.println("Die Eingabe muss eine Zahl ohne Komma oder Punkt sein !!! (int) ");
				SimpleIO.println("");
				againV1=true;
			}
		} while (againV1);
		
		//Vektor 2 einlesen
		
		do {
			try {
				SimpleIO.println("Bitte alle Komponenten von Vektor2 mit 'Enter' getrennt eingeben!");
				
				for (int i=0;i<dim;i++) {
					y[i]=SimpleIO.readInteger();
				}
				againV2=false;
				
			} catch (NullPointerException e) {
				SimpleIO.println("ACHTUNG!!!");
				SimpleIO.println("Die Eingabe muss eine Zahl ohne Komma oder Punkt sein !!! (int) ");
				SimpleIO.println("");
				againV2=true;
			}
			
		} while (againV2);
		
		//Vektoren an den Benutzer ausgeben
		
		SimpleIO.println("Es werden Berechnungen auf Grundlage der folgenden beiden Vektoren durchgeführt:");
		SimpleIO.println("");
		
		for (int i=0;i<dim;i++) {
			SimpleIO.println("      " + x[i] + "           " + y[i]);
		}
		
		return 0;
	}
	public static int SProdukt(int[] x, int[] y) {
		int skalarP=0;
		
		for (int i=0;i<dim;i++) {
			skalarP+=x[i]*y[i];
		}
		
		SimpleIO.println("");
		SimpleIO.println("Das Skalarprodukt der Vektoren beträgt:  " + skalarP + "  !");
		SimpleIO.println("");
		return 0;
	}
	
	
	public static void main (String[] args) {
		int[] a,b;
		a=new int [dim];
		b=new int [dim];
		Vlesen(a,b);
		SProdukt(a,b);
	}
}

dann gibt er mir für die Methode SProdukt folgenden Fehler aus:

Code:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
	at Hallo.SProdukt(Hallo.java:72)
	at Hallo.main(Hallo.java:87)
Ergänzung ()

wäre das so jetzt wie ihr das meint?

den fehler bekomme ich aber halt jetzt immer ... :(

Code:
public static void SProdukt(int[] x, int[] y) {
		int skalarP=0;
		
		for (int i=0;i<dim;i++) {
			skalarP+=x[i]*y[i];
		}
		
		SimpleIO.println("");
		SimpleIO.println("Das Skalarprodukt der Vektoren beträgt:  " + skalarP + "  !");
		SimpleIO.println("");
 
So wies aussieht kann man in Java die übergebenen Referenzen garnicht neu zuweisen. Du müsstest also idealerweise die dim Variable schon in main festlegen und dort die Arrays anlegen. Also so irgendwie:
Code:
public class Hallo {
	static int dim;
	
	public static int Vlesen(int[] x, int[] y) {
		boolean againV1;
		boolean againV2;
		
		//Vektor 1 einlesen
		
		do {
			try {
				SimpleIO.println("Bitte alle Komponenten von Vektor1 mit 'Enter' getrennt eingeben!");
				
				for (int i=0;i<dim;i++) {
					x[i]=SimpleIO.readInteger();
				}
				againV1=false;
				
			} catch (NullPointerException e) {
				SimpleIO.println("ACHTUNG!!!");
				SimpleIO.println("Die Eingabe muss eine Zahl ohne Komma oder Punkt sein !!! (int) ");
				SimpleIO.println("");
				againV1=true;
			}
		} while (againV1);
		
		//Vektor 2 einlesen
		
		do {
			try {
				SimpleIO.println("Bitte alle Komponenten von Vektor2 mit 'Enter' getrennt eingeben!");
				
				for (int i=0;i<dim;i++) {
					y[i]=SimpleIO.readInteger();
				}
				againV2=false;
				
			} catch (NullPointerException e) {
				SimpleIO.println("ACHTUNG!!!");
				SimpleIO.println("Die Eingabe muss eine Zahl ohne Komma oder Punkt sein !!! (int) ");
				SimpleIO.println("");
				againV2=true;
			}
			
		} while (againV2);
		
		//Vektoren an den Benutzer ausgeben
		
		SimpleIO.println("Es werden Berechnungen auf Grundlage der folgenden beiden Vektoren durchgeführt:");
		SimpleIO.println("");
		
		for (int i=0;i<dim;i++) {
			SimpleIO.println("      " + x[i] + "           " + y[i]);
		}
		
		return 0;
	}
	public static int SProdukt(int[] x, int[] y) {
		int skalarP=0;
		
		for (int i=0;i<dim;i++) {
			skalarP+=x[i]*y[i];
		}
		
		SimpleIO.println("");
		SimpleIO.println("Das Skalarprodukt der Vektoren beträgt:  " + skalarP + "  !");
		SimpleIO.println("");
		return 0;
	}
	
	
	public static void main (String[] args) {
		int[] a,b;
        SimpleIO.println("Hallo liebe JAVA-Welt! " +
				"Dies ist ein Programm zur Berechnung von Längen, Skalarprodukten, Kreuzprodukten und Summen von Vektoren");
		SimpleIO.println("Geben Sie bitte ein, wie viele Dimensionen der Raume der Vektoren umfasst!");
		SimpleIO.println("");
		dim=SimpleIO.readInteger();
		
		a=new int [dim];
		b=new int [dim];
		Vlesen(a,b);
		SProdukt(a,b);
	}
}
 
Danke! :) hat geklappt!

Code:
public class Hallo {
	static int dim;
	
	public static void Vlesen(int[] x, int[] y) {
		boolean againV1;
		boolean againV2;
		
		//Vektor 1 einlesen
		
		do {
			try {
				SimpleIO.println("Bitte alle Komponenten von Vektor1 mit 'Enter' getrennt eingeben!");
				
				for (int i=0;i<dim;i++) {
					x[i]=SimpleIO.readInteger();
				}
				againV1=false;
				
			} catch (NullPointerException e) {
				SimpleIO.println("ACHTUNG!!!");
				SimpleIO.println("Die Eingabe muss eine Zahl ohne Komma oder Punkt sein !!! (int) ");
				SimpleIO.println("");
				againV1=true;
			}
		} while (againV1);
		
		//Vektor 2 einlesen
		
		do {
			try {
				SimpleIO.println("Bitte alle Komponenten von Vektor2 mit 'Enter' getrennt eingeben!");
				
				for (int i=0;i<dim;i++) {
					y[i]=SimpleIO.readInteger();
				}
				againV2=false;
				
			} catch (NullPointerException e) {
				SimpleIO.println("ACHTUNG!!!");
				SimpleIO.println("Die Eingabe muss eine Zahl ohne Komma oder Punkt sein !!! (int) ");
				SimpleIO.println("");
				againV2=true;
			}
			
		} while (againV2);
		
		//Vektoren an den Benutzer ausgeben
		
		SimpleIO.println("Es werden Berechnungen auf Grundlage der folgenden beiden Vektoren durchgeführt:");
		SimpleIO.println("");
		
		for (int i=0;i<dim;i++) {
			SimpleIO.println("      " + x[i] + "           " + y[i]);
		}
	}
	
	public static void SProdukt(int[] x, int[] y) {
		int skalarP=0;
		
		for (int i=0;i<dim;i++) {
			skalarP+=x[i]*y[i];
		}
		
		SimpleIO.println("");
		SimpleIO.println("Das Skalarprodukt der Vektoren beträgt:  " + skalarP + "  !");
		SimpleIO.println("");
	}
	
	public static void main (String[] args) {
		SimpleIO.println("Hallo liebe JAVA-Welt! " +
		"Dies ist ein Programm zur Berechnung von Längen, Skalarprodukten, Kreuzprodukten und Summen von Vektoren");
		SimpleIO.println("Geben Sie bitte ein, wie viele Dimensionen der Raume der Vektoren umfasst!");
		SimpleIO.println("");

		dim=SimpleIO.readInteger();

		int[] a,b;
		a=new int [dim];
		b=new int [dim];
		
		Vlesen(a,b);
		SProdukt(a,b);
	}
}
 
das "Problem" ist einfach zu erklären...

Code:
public class Beispiel {

	public static void main(String[] args) {
		String test = "ich bin das original";
		callMethod(test);
		System.out.println(test);
		
		int[] orig = new int[3];
		orig[0]=1;
		orig[1]=2;
		orig[2]=3;
		
		callMethod(orig);
		
		for (int zahl : orig) {
			System.out.println(zahl);
		}
	}

	private static void callMethod(int[] orig) {
		orig = new int[3];

		orig[0]=5;
		orig[1]=6;
		orig[2]=7;
	}

	private static void callMethod(String test) {
		test = new String("ich habe eine neue Instanz");
	}
}

Wenn du in deiner Methode eine neue Instanz erstellst, veränderst du damit nicht die Referenz...


gruss, krizi
 
Da das Problem schon gelöst wurde, kann ich meine Lösung auch mal posten:
Code:
public class Vector {
	protected static int dim;
	protected static int[] x;
	protected static int[] y;
	
	/**
	 * Fragt vom User die Anzahl der Dimensionen ab.
	 */
	protected static int readDimension() {
		int dim = 0;
		
		while (dim <= 0) {
			System.out.print("Geben Sie bitte ein, wie viele Dimensionen die Vektoren haben: ");
			dim = In.readInt();
		}
				
		return dim;
	}

	/**
	 * Gibt die Anzahl der Dimensionen aus.
	 * 
	 * @param dim
	 */
	protected static void writeDimension(int dim) {
		System.out.println("Anzahl der Dimensionen: " + dim);
	}
	
	/**
	 * Fragt vom User einen Vektor ab.
	 * 
	 * @param bezeichner - Vektorbezeichnung für die Anzeige
	 * @return Integerarray oder null bei Fehler
	 */
	protected static int[] readVector(char bezeichner) {
		if (dim > 0) {
			
			System.out.println("Bitte alle Komponenten von Vektor " + bezeichner + " mit 'Enter' getrennt eingeben!");
			
			int[] z = new int[dim];
			for (int i = 0; i < dim; i++) {
				System.out.print("Vektor " + bezeichner + ", " + (i+1) + ". Dimension: ");
				z[i] = In.readInt();
			}			
			
			return z;
			
		} else {
			System.out.println("Fehler: Die Anzahl der Dimensionen ist ungültig. Abbruch!");
			
			return null;
		}
	}
	
	/**
	 * Gibt den Inhalt eines Vektors aus.
	 * 
	 * @param bezeichner - Vektorbezeichnung für die Anzeige
	 * @param z - Integerarray
	 */
	protected static void writeVector(char bezeichner, int[] z) {
		if (dim > 0) {
			if (z != null) {
				System.out.print(bezeichner + " = {");
			
				for (int i = 0; i < dim; i++) {
					System.out.print(" " + z[i] + " ");
				}
			
				System.out.println("}");
				
			} else {
				System.out.println("Fehler: Der Vektor existiert nicht. Abbruch!");
			}
			
		} else {
			System.out.println("Fehler: Die Anzahl der Dimensionen ist ungültig. Abbruch!");
		}
	}

	/**
	 * Berechnet das Skalarprodukt zweier Vektoren.
	 * 
	 * @param x - erster Vektor
	 * @param y - zweiter Vektor
	 * @return Skalarpodukt
	 */
	protected static int calculateSkalarproduct(int[] x, int[] y) {
		int ergebnis = 0;
		
		if (x != null && y != null) {
			for (int i = 0; i < dim; i++) {
				ergebnis += x[i] * y[i];
			}
			
		} else {
			System.out.println("Fehler: Mindestens einer der Vektoren existiert nicht. Abbruch!");
		}
		
		return ergebnis;
	}
	
	/**
	 * Programmeinsprungpunkt
	 * 
	 * @param args - Kommandozeilenparameter
	 */
	public static void main(String[] args) {
		
		
		System.out.println("Hallo liebe JAVA-Welt!\n" +
						   "Dies ist ein Programm zur Berechnung von Längen, Skalarprodukten, Kreuzprodukten und Summen von Vektoren");
		System.out.println();
		
		dim = readDimension();
		x = readVector('x');
		y = readVector('y');
		
		System.out.println();
		writeDimension(dim);
		writeVector('x', x);
		writeVector('y', y);
		System.out.println("Das Skalarprodukt von x und y beträgt " + calculateSkalarproduct(x, y) + ".");
	}
	

}
Was In.readInt() macht, sollte klar sein. ;)

Ausgabe:
Hallo liebe JAVA-Welt!
Dies ist ein Programm zur Berechnung von Längen, Skalarprodukten, Kreuzprodukten und Summen von Vektoren

Geben Sie bitte ein, wie viele Dimensionen die Vektoren haben: 4
Bitte alle Komponenten von Vektor x mit 'Enter' getrennt eingeben!
Vektor x, 1. Dimension: 3
Vektor x, 2. Dimension: 2
Vektor x, 3. Dimension: 1
Vektor x, 4. Dimension: 0
Bitte alle Komponenten von Vektor y mit 'Enter' getrennt eingeben!
Vektor y, 1. Dimension: 0
Vektor y, 2. Dimension: 1
Vektor y, 3. Dimension: 2
Vektor y, 4. Dimension: 3

Anzahl der Dimensionen: 4
x = { 3 2 1 0 }
y = { 0 1 2 3 }
Das Skalarprodukt von x und y beträgt 4.

Der Code lässt sich prima so umwandeln, dass man da eine ganze Vektorklasse daraus bauen kann.
 
Zuletzt bearbeitet: (Prüfung auf null hinzugefügt.)
Um dein Problem nochmal etwas genauer zu erläutern hier ein paar Infos warum es schief ging:

In deiner ersten Umsetzung wurde ja bereits erwähnt, dass die Neuzuweisung die Variablen überschrieben hätte. Das ist nur teilweise richtig. Du erstellst in der main-Methode zwei Arrays mit dem Wert dim, der zu dem Zeitpunkt noch gar nicht festgelegt ist, da er noch nicht eingelesen wurde. Da Java so nett ist bekommst du die Variable also mit 0 initialisiert. Du erstellt in der nächsten Zeile also zwei Arrays der Länge Null.

Der zweite Fehler ist, dass du einen primitiven Datentyp erstellst und diesen an die Funktion übergibst. Primitive Datentypen werden aber wenn man sie einer Funktion übergibt nur kopiert und nicht referenziert, es liegt also das sogenannte Call-By-Value vor und somit bleiben deine Variablen ungeändert, egal was du damit in der Funktion selber anstellst. Beim Funktionsaufruf werden die Werte nämlich einfach auf den Stack gepusht und dann wird mit dieser Kopie weiter gerechnet. Willst du einen Wert übergeben, der durch die Funktion geändert werden kann, dann musst du eine eigene Klasse dafür erstellen und deine Funktionen entsprechend anpassen, da dann die Referenz übergeben wird und der Funktionsaufruf per Call-By-Reference passiert. In Sprachen wie C hat man darüber die Kontrolle, da man selber entscheiden kann ob man die Variable übergibt oder die Referenz auf den Speicherblock wo das ganze liegt, in Java entscheidet sich das anhand der übergebenen Klasse, also entweder primitiver Datentyp und Call-By-Value oder eigene Klasse und Call-By-Reference. Primitive Datentypen sind übrigens in Java alle die, die mit einem kleinen Buchstaben beginnen, also byte, int, long, float, etc. Es gibt auch noch die mit dem großen Buchstaben vorne dran, also Byte, Integer, Long, Float, etc. Diese werden allerdings bei einem Funktionsaufruf per sogenanntem Unboxing und anschließendem Boxing in ihre primitiven Formen umgewandelt und es wird damit gerechnet, also auch wieder nur eine Kopie.

Der letzte Fehler passiert dann in der Methode für dein Skalarprodukt, da deine Arrays immer noch die Länge 0 haben. Er wird also gar nicht erst in die for-Schleife reinspringen, da deine Abbruchbedingung direkt erfüllt ist.

Ich würde alle verwendeten Variablen in dem Fall als static in der Klasse definieren (dim, x, y), dann als erstes die Dimension abfragen, Werte einlesen und zum Schluss rechnen, alles jeweils in einer eigenen Methode.

//Edit: kleiner Fehler beseitigt, Autounboxing vergessen.
 
Zuletzt bearbeitet:
Glückwunsch, dass nun alles klappt, aber das was du geschrieben hast hat mit Objektorientierung ca. 0 zu tun.
Als kleine Herausforderung könntest du das Ganze nochmal schreiben ohne das Schlüsselwort "static" zu verwenden, stattdessen arbeite mit Objekten (z.B. new Vector()).

"static" ist ein für Anfänger verführerisches Schlüsselwort, weil man damit schön einfach "globale" Variablen definieren kann. Guter Stil ist das nicht und bei größeren Programmen kommt man damit in Teufelsküche. Also lieber auch schon im kleinen "ordentlich" programmieren.
 
so würde meine Vector-Klasse wohl aussehen...

Code:
public final class Vector {
	private final int[] values;
	
	private Vector(final int dimension) {
		values = new int[dimension];
	}

	public static Vector emptyVector(final int dimension) {
		return new Vector(dimension);
	}
	
	public static Vector create(final int ... values) {
		final Vector result = new Vector(values.length);
		result.setComponents(values);
		return result;
	}
	
	public int getDimension()
	{
		return values.length;
	}
	
	public void setComponents(final int[] values)
	{
		if (values.length != this.values.length) {
			throw new IllegalArgumentException("wrong dimension");
		}

		for (int i = 0; i < values.length; i++) {
			this.values[i] = values[i]; 
		}
	}
	
	public void setComponent(final int index, final int value)
	{
		if (index < 0 || index >= values.length) {
			throw new IllegalArgumentException("index out of bounds");
		}
		
		values[index] = value;
	}

	public int getComponent(int index) {
		if (index < 0 || index >= values.length) {
			throw new IllegalArgumentException("index out of bounds");
		}
		return values[index];
	}
	
	public String toString() 
	{
		final StringBuilder text = new StringBuilder();
		text.append("(");
		for (int i = 0; i < values.length; i++) {
			text.append(String.valueOf(values[i]));
			text.append(',');
		}
		text.setCharAt(text.length()-1, ')');
		
		return text.toString();
	}

	public static int scalarProduct(final Vector v1, final Vector v2)
	{
		if (v1.getDimension() != v2.getDimension()) {
			throw new IllegalStateException("different dimensions");
		}
		
		int result = 0;
		
		for (int i = 0; i < v1.getDimension(); i++) {
			result += v1.getComponent(i) * v2.getComponent(i);
		}
		
		return result;
	}	
}

Kann meinem Vorredner auch nur zustimmen...
Außerdem ist die Rückgabe von null-Werten auch nicht wirklich sinnvoll um einen Fehlerfall zu signalisieren...
 
Zuletzt bearbeitet:
1668mib schrieb:
so würde meine Vector-Klasse wohl aussehen...

Code:
public final class Vector {
	private final int[] values;
	
	private Vector(final int dimension) {
		values = new int[dimension];
	}

	public static Vector emptyVector(final int dimension) {
		return new Vector(dimension);
	}
	
	public static Vector create(final int ... values) {
		final Vector result = new Vector(values.length);
		result.setComponents(values);
		return result;
	}
	
	public int getDimension()
	{
		return values.length;
	}
	
	public void setComponents(final int[] values)
	{
		if (values.length != this.values.length) {
			throw new IllegalArgumentException("wrong dimension");
		}

		for (int i = 0; i < values.length; i++) {
			this.values[i] = values[i]; 
		}
	}
	
	public void setComponent(final int index, final int value)
	{
		if (index < 0 || index >= values.length) {
			throw new IllegalArgumentException("index out of bounds");
		}
		
		values[index] = value;
	}

	public int getComponent(int index) {
		if (index < 0 || index >= values.length) {
			throw new IllegalArgumentException("index out of bounds");
		}
		return values[index];
	}
	
	public String toString() 
	{
		final StringBuilder text = new StringBuilder();
		text.append("(");
		for (int i = 0; i < values.length; i++) {
			text.append(String.valueOf(values[i]));
			text.append(',');
		}
		text.setCharAt(text.length()-1, ')');
		
		return text.toString();
	}

	public static int scalarProduct(final Vector v1, final Vector v2)
	{
		if (v1.getDimension() != v2.getDimension()) {
			throw new IllegalStateException("different dimensions");
		}
		
		int result = 0;
		
		for (int i = 0; i < v1.getDimension(); i++) {
			result += v1.getComponent(i) * v2.getComponent(i);
		}
		
		return result;
	}	
}

Kann meinem Vorredner auch nur zustimmen...
Außerdem ist die Rückgabe von null-Werten auch nicht wirklich sinnvoll um einen Fehlerfall zu signalisieren...

oh man, wenn ich sowas lese, dann merke ich erst wie stark ich noch anfänger bin. kann mir vielleicht einer das mal schritt für schritt näher erklären. ich sehe dass objekte erzeugt werden, aber mehr auch nicht :-/...

Und ich glaube euch, dass meine vaiante nicht gerade die proessionellste ist ;)
 
Die Vectorklasse oben ist noch nicht das fertige Programm, es ist ein Stück Code, welches du in anderen Programmen nun immer wieder verwenden könntest.

Praktisch schreibst folgenden Code in eine main-Methode einer anderen Klasse. Diese Klasse dient nur dazu die Vectorklasse zu verwenden. Ich lege zu diesem Zweck immer eine Klasse Main an, die keine anderen Sinn hat als das Programm zu starten. Dieses hat dann auch nur eine main-Methode, in der dann sowas ähnliches wie folgt drinstünde:

PHP:
Vector vector1 = Vector.create(1, 2);
Vector vector2 = Vector.create(3, 4);
int ergebnis = Vector.scalarProduct(vector1, vector2);


In dem Beispiel Vector-Klasse wird zwar immer noch mit static gearbeitet, aber immerhin werden schon richtige Vector-Objekte erzeugt.



Ein rein objektorientierte Lösung würde (in der Verwendung) so aussehen:
PHP:
Vector vector1 = new Vector(1, 2);
Vector vector2 = new Vector(3, 4);
int ergebnis = vector1.scalarProduct(vector2);


Warum ist static "böse"?

Man möchte doch jeden Vektor unabhängig voneinander speichern. Das heißt, dass jeder Vector seinen eigenen Zahlenwerte besitzt. Definiert man die Datenfelder jedoch static, so werden bei Änderung des Feldes die Werte aller Vektoren geändert, was man nicht will.

Kurz erklärt ist ein static-Feld keine Eigenschaft der Objekte, sondern eine Eigenschaft der Klasse, um das deutlich zu machen sollte man diese auch immer mit dem Klassennamen lesen und schreiben, z.b.

MeinKlassenname.meinStatischeFeld = 1;

Leider kann man in Java statische Felder auch über Objektinstanzen (das sind die Variablen, die man mit new erzeugt hat) ansprechen. Das sollte man auf jeden Fall vermeiden, weil es dann so aussieht als gehöre der Wert zum Objekt, was ja nicht stimmt.


Ich hoffe ich habe etwas mehr Licht in die Sache gebracht und Dich nicht nur mehr verwirrt.

Ich rate Dir, Dir ein Anfängerbuch für Java anzuschaffen, wo Du diese Konzepte alle mal nachlesen kannst.
 
@Banthor: Ich mach da mittlerweile gerne statische Methoden, weil man bei solchen Sachen oft nicht weiß was passiert:
vector1.add(vector2);
klar kann man da auch schreiben dann
vector1.plus(vector2);
was dann eher dem mathematischen Plus-Operator entsprechen würde.

Aber sicher ist man dennoch nicht, ob vector1 unverändert bleibt.
[Natürlich weiß man es bei der statischen auch nicht, aber warum sollte da etwas verändert werden? ^^]

Genauso mach ich gerne statische Creator-Methoden statt überladenen Konstruktoren (hier wäre es auch problematisch, einen Null-Vektor mit 100 Feldern mit new Vector(100) zu machen sonst, könnte ja auch ein eindiemnsionaler Vector sein - gut, das gibt nicht arg viel sinn ja... ^^)
 
Martin240 schrieb:
Primitive Datentypen werden aber wenn man sie einer Funktion übergibt nur kopiert und nicht referenziert, es liegt also das sogenannte Call-By-Value vor und somit bleiben deine Variablen ungeändert, egal was du damit in der Funktion selber anstellst.
Das stimmt. Noch zur Info, wenn ein int[] übergeben wird, arbeitet Java mit der Referenz.

gruss, krizi
 
Ist int[] ein primitiver Datentyp? oO

Und Java kennt nur Call-by-Value, es arbeitet immer gleich bei der Parameterübergabe. Wirklich. Denn bei Objekten werden die Adressen by-Value übergeben... was dann aber im Grunde nichts anderes als eine Referenz ist.
 
Zurück
Oben