ArrayList casten

unknown

Bekanntes Mitglied
Hallo

Weiss jemand wie man ArrayLists casten kann?
Ich möchte folgendes tun, ein ArrayList<Object> in ein ArrayList<String> casten.

[Java]
ArrayList<String> names = new ArrayList<String>();
names.add("it's");
names.add("just");
names.add("a");
names.add("test");
//
ArrayList<Object> names2 = new ArrayList<Object>();
names2.add(names);
//
ArrayList<String> names3 = new ArrayList<String>();
names3 = (ArrayList<String>) names2.get(0);
[/Java]
 
Zuletzt bearbeitet:
Das funktioniert so wie jeder andere cast auch 🙂

Java:
ArrayList<Object> objects = new ArrayList<Object>();
ArrayList<String> strings = (ArrayList<String>)objects;
 
ok jetzt hab' ich folgendes gemacht:
Java:
ArrayList<String> names3 = new ArrayList<String>();
names3 = (ArrayList<String>)names2.get(0);
und bekomme eben diese Warnung:
"Type safety: Unchecked cast from Object to ArrayList<String>"

was soll noch gemacht werden?
 
Das funktioniert so wie jeder andere cast auch 🙂

Java:
ArrayList<Object> objects = new ArrayList<Object>();
ArrayList<String> strings = (ArrayList<String>)objects;


Nee, das funktioniert so nicht. Mit folgendem Trick geht es, da die ArrayList<Object> zu List<?> gecastet wird und dann zu einem String.

Code:
names3 = (ArrayList<String>)(List<?>)names2;
 
Naja ist doch auch klar.
Du hast eine Liste von Objekte, da kann alles mögliche drin sein. Jetzt will du daraus eine Liste von Strings machen, das kann dann natürlich krachen wenns auf einmal keine Strings sind. Da warnt der Compiler dich dann.
 
Du hast eine Liste von Objekte, da kann alles mögliche drin sein. Jetzt will du daraus eine Liste von Strings machen, das kann dann natürlich krachen wenns auf einmal keine Strings sind. Da warnt der Compiler dich dann.


Deshalb geht der Compiler davon aus, dass beim Casten der Programmierer genau weiss, was er tut. Wenn er es nicht weiss, dann soll es aus krachen.
 
Nee, das funktioniert so nicht. Mit folgendem Trick geht es, da die ArrayList<Object> zu List<?> gecastet wird und dann zu einem String.

Code:
names3 = (ArrayList<String>)(List<?>)names2;

also du meinst so etwas?
Java:
names3 = (ArrayList<String>)(List<?>)names2.get(0);
ich bekomme eine Errormeldung:
Cannot cast from List<capture#1-of ?> to ArrayList<String>
 
also du meinst so etwas?
Java:
names3 = (ArrayList<String>)(List<?>)names2.get(0);
ich bekomme eine Errormeldung:
Cannot cast from List<capture#1-of ?> to ArrayList<String>

Nein, names3 enthält die ganze Liste von names2, also geht names3.get(0). Sofern Du nur ein Element benötigst, geht auch

Code:
		ArrayList<Object> objs = new ArrayList<Object>();
		
		objs.add("Hallo");
		objs.add("Welt");
		
		String s = (String)objs.get(0);
 
aber der folgende Code funktioniert ja auch nicht.
Java:
 names3 = (ArrayList<String>)(List<?>)names2;

Meldung: Cannot cast from List<capture#1-of ?> to ArrayList<String>
 
>names3 = (ArrayList<String>)(ArrayList<?>)names2;

bevor man so was schreibt, lässt man die Generics lieber gleich weg.

Code:
ArrayList<String> stringList =  (ArrayList)objectList;
 
kann da Joe eigentlich nur zustimmen da der compiler TYPE-EREASURE anwendet ... *um angeblich abwärtskompatibel zu bleiben ...*

heißt : egal wie man auch rum-castet und wie sehr man generics in ein ander verschachtelt ... der compiler macht am ende einen RAW-type draus ...

so wird dann z.b. aus

Java:
List<List<Vector<HashMap<String, Object>>>>

nach dem anweden von Type Ereasure nur noch eine ganznormale

Java:
List

draus ...

daher ist es egal wie man da rumcastet ... der einzige der sich beschwert ist der compiler ... mit ner menge type-cast-warnings ...
wenn man aber innerhalb seines codes ganz genau weis was man macht und innerhalb des codes dafr sorgt das es nicht irgendwann zu fehlern kommt ... dann wird sich die VM auch nicht beschweren und die app ganz normal ablaufen ... egal ob ihr dann risiege verschachtelte casts macht und gleich von vornherein mit RAW-types arbeitet und die warnings ignoriert ...
 
und jetzt ist ein anders Problem aufgetaucht.

Ich benutze ArrayList "names" als einen Zwischenbehälter. Das heisst, jedes mal wenn names2 durch names gefüllt wird, sollen die Inhalte von names gelöscht werden, so dass ich es nochmals verwenden kann.

Und wenn ich jetzt die Methode clear() aufrufe, dann werden die Inhalte in names2 auch gelöscht!
habt ihr eine Lösung dafür?

Java:
ArrayList<String> names = new ArrayList<String>();
names.add("it's");
names.add("just");
names.add("a");
names.add("test");
		
ArrayList<Object> names2 = new ArrayList<Object>();
names2.add(names);
		
ArrayList<String> names3 = new ArrayList<String>();
names3 = (ArrayList<String>)names2.get(0);
names.clear();
System.out.print(names2.get(0));
 
hat was mit referenzen und objekten zu tun ...

so wie du es jetzt machst verschiebst du immer nur referenzen ... hast aber im endeffekt nur ein objekt *vielleicht ist STRING nicht grad die beste wahl für ein beispiel -> stringpool und so*

was du tun musst ist die objekte kopieren ... so das du zwei objekte hast ... und nicht nur die referenzen ...
 
1. Du machst eine List von Strings. names

2. Dann addest du die List in eine ArrayList -->names2 --> ArrayList mit einem Element, der Liste names

3 .Dann clearst du names.

Im Punkt 2 hast du genau diese Liste in die Liste 2 getan. Genau dieses Objekt. Das gleiche. Nun ist Leer...

EDIT:
hier ein Bsp:
Java:
import java.util.ArrayList;
import java.util.List;

public class XX {

	public static void main(String[] args) {
		
		Car car = new Car();
		car.name = "LADA";
		
		List<Car> cars = new ArrayList<Car>();
		cars.add(car);
		
		System.out.println(cars.get(0).name);
		
		car.name = "DACIA";
		
		System.out.println(cars.get(0).name);
	}

	
	static class Car {
		public String name;
	}
}
 
Zuletzt bearbeitet:
ich denke das dir das problem nicht klar wird da du irgendwas in eine List<Object> adden willst ... und deine List<String> ist nunmal auch ein Object ... wesshalb der compiler das macht ...


du musst also nicht die List<String> selbst adden ... sondern druchiterieren und alle elemente der List<String> in die List<Object> kopieren


*gibts da nich sogar ne methode die das macht ?*
 
Ich will aber, dass der Inhalt von names wirklich in names2 kopiert wird. Eine Referenz bringt mir rein gar nichts.

Was wäre der richtige code, wenn ich eine Kopie möchte und keine Referenz. So Dass names2 von names völlig unabhängig wird.
 
wie bereits erwähnt : erstmal anstatt die liste selbst zu adden deren inhalt durchgehen ...

geht mit foreach oder Iterator
 
Da gibt es keine vorgefertigte Methode, dies musst du selbst implementieren.

Mit einer schliefe über die Liste iterieren und jeden Eintrag selbst in eine Liste kopieren
 
Code:
List<String> names2 =new ArrayList<String>(names);
oder
Code:
List<String> names2 =new ArrayList<String>();
Code:
names2.addAll(names);
 
Aber das bringt mir auch nichts, Wenn das 1. Element von names2 = das 1. Element von names etc.

Was ich möchte ist folgendes:
das 1. Element von names2 was ja Objekte beinhalt, soll alle Elemente der names beinhalten (und keine Referenze).
und dann möchte ich names leeren und neue Namen einfügen, ohne dass sich das erstle Element von names2 dadurch ändern lässt 🙂
 
Probier doch mal aus was dir Der_Müde_Joe geschreiben hat, und wenn das nicht funktioniert, dann zeig ein bisschen Code was du hast und beschreib was du haben willst.

(Hatte ja ganz vergessen, dass die Listentypen in Java den Kopierkonstruktor haben (der macht meiner Meinung nach genau das was du moechtest))
 
Ich verstehe das so nach deinen erklärungen:
(Immer schön eine neue List machen. sonst ist ja eben die gleiche Refenrenz)
Java:
List<String> names = new ArrayList<String>();
names.add("foobar");
names.add("foobar2");

List<Object> strangeThing = new ArrayList<Object>();
strangeThing.add(names);

names = new ArrayList<String>();
names.add("hello");
names.add("world");

strangeThing.add(names);
 
Sagen wir mal wir haben verschiedene Farben und jede Farbe hat einen ID:

So habe ich in jedem Element von ArrayList "farben" die entsprechende Informationen für jede Farbe.
Sprich im Element 0 habe ich die Infos für "white" im Element 1 die für "black" etc.


Also es würde mir nichts bringen wenn dass 1. Element von farbe ID wäre und das 2. Name etc. sondern sie sollen alle in einem Element sein 🙂
 
Zuletzt bearbeitet:
Ok das mit names = new ArrayList<String>(); würde funktionieren 🙂
Aber wieso funktioniert es so und nicht mit clear()? Weil so ist ja der vorherige Inhalt auch nicht mehr vorhanden.
 
Stell dir mal vor du hast ein Auto. (names)
und eine Garage (List<Object>)

Das Auto steht vor der Garage. Jetzt packst du ein Kasten Bier rein.
Das stellts du das Auto in die Garage. (names2.add(names))

In der Garage haste nun dein Auto mit dem Kasten Bier.

In der zwischenzeit wird das Bier im Auto getrunken. (clear())

Ob es nun in der Garage steht oder net...Das Bier ist weg.

Wenn du higegen ein neues Auto holst (new) und noch ein paar Flaschen Wein darin hast, und dies dann trinkst ist im anderen Auto das Bier immer noch da ;-)
 
Zuletzt bearbeitet:
eine weitere Frage:

wenn man zwei ArrayLists wie folgt hat:

Java:
ArrayList<String> test1 =  new ArrayList ArrayList<String>();
ArrayList<String> test2 =  new ArrayList ArrayList<String>();

test1 =  test2;

Dann sind beide ArrayLists von einander abhängig. sprich, wenn man im test2 etwas ändert, dann wird dieselbe Änderung auch im test1 vorgenommen.
Gäbe es eine Möglichkeit eine richtige Kopie von test1 zu machen und keine Referenz? So, dass man test2 ändern kann, ohne dass test 1 geändert wird? 🙂
 
ja

Java:
ArrayList<String> test1 =  new ArrayList ArrayList<String>();
//fuelle test1 mit werten
ArrayList<String> test2 =  new ArrayList ArrayList<String>(test1);
// test2 ist jetzt eine kopie von test1


wenn du jetzt zum Beispiel ein objekt aus test1 entfernst, dann ist es noch immer in test2 vorhanden.

ACHTUNG, die Objekte in der Liste sind aber noch immer die selben
 
Hier bitte schoen ein kleines Beispiel

Java:
		ArrayList<StringBuilder> test1 = new ArrayList<StringBuilder>();
		test1.add(new StringBuilder ("Hallo 1"));
		test1.add(new StringBuilder("Hallo 2"));
		
		ArrayList<StringBuilder> test2 = new ArrayList<StringBuilder>(test1);
		System.out.println("Groeße von Test1:"+test1.size());
		System.out.println("Groeße von Test2:"+test2.size());
		System.out.println();
		test1.remove(1);
		System.out.println("Groeße von Test1:"+test1.size());
		System.out.println("Groeße von Test2:"+test2.size());
		test1.get(0).append("jetzt wird bei test1 was hinzugefuegt");
		
		System.out.println(test2.get(0));

Ich musste um dies zu verdeutlichen StringBuilder verwenden und nicht String, da die Klasse String immutable sind und daher dort der Effekt nicht auffallen würde,
 
eine ähnliche Frage bezüglich der Objekten

wenn man so was hat:
Java:
BesipielObject a = new BesipielObject(); 
BesipielObject b = a;

b wird die gleiche Referenz haben wie a . sprich ändert man etwas in b, wird die Änderung in a auch übernommen.

kann man da auch ähnlich wie beim ArrayList eine richtige Kopie von a machen und keine Referenzierung?

//
und noch eine Frage, die nicht zum Topic passt, aber ich stelle sie jetzt mal 🙂
Es gibt doch eine Alternative zum Import
Wenn ich beispielsweise "java.awt.Grapics;" nicht importiere, dann muss ich doch überall wo ich ein Type "Graphics" benutze, das Objekt "Grapics" aufrufen.
Wie sieht der entsprechende Befehl genau aus?
 
kann man da auch ähnlich wie beim ArrayList eine richtige Kopie von a machen und keine Referenzierung?
Wenn es sich um ein Objekt einer selbst definierten Klasse handelt muss man sich selbst darum kümmern. Manche Standard Objekte lassen sich mit clone() duplizieren.
und noch eine Frage, die nicht zum Topic passt, aber ich stelle sie jetzt mal 🙂
Es gibt doch eine Alternative zum Import
Wenn ich beispielsweise "java.awt.Grapics;" nicht importiere, dann muss ich doch überall wo ich ein Type "Graphics" benutze, das Objekt "Grapics" aufrufen.
Wie sieht der entsprechende Befehl genau aus?
Was für ein Object aufrufen? Keine Ahnung was genau Du meinst aber wenn man die Klasse oder das Package nicht in der import Anweisung angibt, muss im Code bei der Deklaration und Initialisierung immer den vollständigen Namen der Klasse - in diesem Fall "java.awt.Graphics" - angeben.
 
es gibt kein Objekt "Grapics", selbst ohne Tippfehler, du meinst doch wohl die Klasse,
was du in den Sätzen aber sagen willst bleibt verschlossen,

Import spart allein etwas Tipparbeit,
ohne Import musst exakt eines tun: überall im Quelltext die Klasse lang schreiben wo sie vorher kurz stand,
absolut nichts sonstiges ändert sich

------

beim Kopieren von Objekten ist noch ein zusätzlicher Punkt zu beachten,
ob das Objekt a an sich dasselbe oder eine Kopie ist ist eine Frage,
die andere was mit intern referenzierten Objekten passiert

Java:
ArrayList<String> test1 =  new ArrayList ArrayList<String>();
ArrayList<String> test2 =  Kopie von test1
soll test2 zwar eine andere Liste sein, aber noch auf dieselben String-Objekte intern verweisen oder gar die Strings auch kopieren?
bei unveränderlichen Strings ist das relativ egal, wenn aber intern auf komplizierte Ressourcen wie Swing-GUI, Socket, Datenbank oder einfach die gesamte restliche Welt verwiesen wird, dann wird die Kopie schon sehr fraglich

alles kopieren geht z.B. mit Serialisierung
Deep-Copy von Java-Objekten Der Informatik Student

der einfache Fall wird vielleicht von clone() geschafft
Object.clone() bzw wie klonen in Java? :: Fachsimpelei :: die-informatiker.net

üblicher ist aber doch ein Konstruktor, der manuell die nötigen Daten kopiert

> und wie ginge das?

selber im Internet lernen ist kein Weg?
 
Sorry der Thread ist schon älter...
wie AmunRa geschrieben hat:
Java:
ArrayList<String> test1 =  new ArrayList ArrayList<String>();
//fuelle test1 mit werten
ArrayList<String> test2 =  new ArrayList ArrayList<String>(test1);
// test2 ist jetzt eine kopie von test1

aber genau das obige verhindert, dass man:
@SuppressWarnings("unchecked")
im eclipse angeben muss um zu compilieren!
Suuper😀! Vielen Dank.
 
Sorry, aber ich verstehe Deine Fragestellung gerade nicht. Bitte starte doch einen eigenen Thread mit funktionierendem Java Code und zeig uns dann, wo Du eine SupressWarnings anfügen musst, damit etwas übersetzt.

Vielen Dank.
 
Guten Abend KonradN
obiges Problem hatte mich genervt.
Immer wenn ich ein Array egal welcher ART Klonen wollte, musste ich immer im Eclipse:
@SuppressWarnings("unchecked")
oberhalb der Variable resp. der Methode eintragen, sonst hat mir Eclipse Warnungen ausgegeben.
Mit dem Post von AmunRa konne ich diese clones erstellen ohne Eclipse-Warnung.

Das hat mich halt gefreut und ich wollte mich nur bei AmunRa bedanken.
Gruss Richi

PS. Finde Ihre Hilfen echt Super, schade dass ich Sie nicht Persönlich kenne.
 
Danke für die Klarstellung- da hatte ich Dich falsch verstanden.

Generell sollte man clone() auch nicht verwenden (als Best Practice) und statt dessen Factory Methoden oder Konstruktoren verwenden. Und das ist, was du unter dem Strich gemacht hast mit der Anpassung.

Auch Super, dass du so Feedback gibst - das ist immer wieder gern gesehen und motiviert. Vielen Dank!
 

Zurück
Oben