java generics wildcard compiling error (generic of generic) - java

Hello I have a compiling problem with this peace of code. How can I perform a safe add to data variable?
import java.util.*;
public class Foo
{
private TreeSet<? extends Collection<String>> data;
public Foo()
{
data = new TreeSet<ArrayList<String>>();
data.add("Goofy"); //this action generates a compile error
}
}

You're trying to add a String to a TreeSet of ArrayLists of Strings. You would need to add an ArrayList. Probably
ArrayList<String> list = new ArrayList<>();
list.add("Goofy");
data.add(list);
That is, assuming you're not using an overcomplicated design, which you very much probably are.

data is a collection of ArrayList and you are trying to add a String
You need to add the String to an array list first
ArrayList<String> list = new ArrayList<String>();
list.add("Goofy");
data.add(list);
or change data to be a TreeSet of Strings
private TreeSet<String> data;
data = new TreeSet<String>();
data.add("Goofy");

Related

Android extract array of properties of array of objects

I was wondering if there's an effective way to extract an array of properties from an array of custom class objects. For example if I have something like this:
public class MyClass {
private Double p1;
private String p2;
private MyProperty p3;
public MyClass() {}
}
and in somewhere I have an ArrayList filled with objects of this class:
ArrayList<MyClass> listOfObjects = new ArrayList<>();
and I'd like to get a list of one of the properties:
ArrayList<MyProperty> listOfP3 = new ArrayList<>();
ArrayList<Double> listOfP1 = new ArrayList<>();
All I can think of is iterating through listOfObjects and copying the desired properties one by one to a new array... Is there a better way to do this?
EDIT:
If possible one that works with Java 7 also
Probably the cleanest way to do it is to use Streams. Something like this:
List<String> listOfP2= listOfObjects.stream().map(x->x.getP2()).collect(Collectors.toList());
Of course in MyClass you need to add a getter for those fields.
In Java 8 and higher, you can utilize the stream API (as #Amongalen already answered). There is a different possibility of accessing methods: Instead of x -> x.getP1() you can just write MyClass::getP1:
List<Double> p1List = myObjects.stream().map(MyClass::getP1).collect(Collectors.toList());
List<String> p2List = myObjects.stream().map(MyClass::getP2).collect(Collectors.toList());
List<MyProperty> p3List = myObjects.stream().map(MyClass::getP3).collect(Collectors.toList());

LinkedList<class> merge with more than 2

I doing small game with pairs of images than need to be paired and I got in to trouble with merging all LinkedList that they object is classes that posses constructor. They store x,y and cropped img. What I can do to merge this lists to one, when node doesn't work. My goal is to have one LinkedList that will shuffle it over the frame.
What I got
and what i try to achive
Can't do this with addAll ,as i have few LinkedList that refer to different classes. Every class have different img and animation to it.
private LinkedList<Odkryte00> os = new LinkedList<Odkryte00>();
private LinkedList<Odkryte01> os2 = new LinkedList<Odkryte01>();
private LinkedList<Odkryte02> os3 = new LinkedList<Odkryte02>();
private LinkedList<Odkryte03> os4 = new LinkedList<Odkryte03>();
private LinkedList<Odkryte04> os5 = new LinkedList<Odkryte04>();
private LinkedList<Odkryte05> os6 = new LinkedList<Odkryte05>();
It sounds like you want to merge multiple LinkedLists together and randomize the items in the combined list so you can shuffle the pieces of the board in the image you show. This is very easy to accomlish in Java and there are already built-in methods to do so using Collections.
Noting from your update
You want to have a LinkedList of various types of objects as your final list, this is still very possible to accomplish using addAll() there just need to be a few edits from what I was showing earlier.
To do this we return:
LinkedList<Object>
From the combineAndShuffle() method I put together earlier, like so:
import java.util.Collections;
import java.util.LinkedList;
public class Test{
#SafeVarargs
public static LinkedList<Object> combineAndShuffle(LinkedList<?>... l){
//must be <Object> because it needs to hold multiple types of objects
LinkedList<Object> finalList = new LinkedList<>();
//use <?> wildcard because we are unsure what value we will hit
for(LinkedList<?> list: l) {
finalList.addAll(list);
}
//shuffle the list
Collections.shuffle(finalList);
return finalList;
}
public static void main(String [] args){
//list of strings
LinkedList<String> listA = new LinkedList<>();
listA.add("One");
listA.add("Two");
//list of integers, so a different class type
LinkedList<Integer> listB = new LinkedList<>();
listB.add(3);
listB.add(4);
LinkedList<Object> combinedList = combineAndShuffle(listA, listB);
for(Object item: combinedList)
System.out.println(item);
}
}

Java wrapping a collection

I need to wrap five classes: linkedlist, treeset, hashset, and two classes I created myself.
The wrapper and my two classes are all implementing the same interface.
this is the wrapper constructor:
private Collection <String> collection;
public CollectionFacadeSet(java.util.Collection<java.lang.String> collection){
this.collection = collection;
}
now, in another class I want to create a 5 cell array that each cell houses a different set.
This line is OK:
static CollectionFacadeSet[] setArray = new CollectionFacadeSet[5];
BUT, when I create a method that fills the cells:
private static void initializieArray(){
setArray[0] = CollectionFacadeSet(HashSet<String>);
}
it throws me an error:
Syntax error on token ">", Expression expected after this token
How to initiate each cell with a different set type?
The expression
setArray[0] = CollectionFacadeSet(HashSet<String>);
is invalid. You would need something like
setArray[0] = new CollectionFacadeSet(new HashSet<String>());
instead.
static CollectionFacadeSet[] setArray = new CollectionFacadeSet[5];
Array will store the objects of CollectionFacadeSet so use new
setArray[0] = new CollectionFacadeSet(new HashSet<String>());

Why can't you have a "List<List<String>>" in Java? [duplicate]

This question already has answers here:
Is List<Dog> a subclass of List<Animal>? Why are Java generics not implicitly polymorphic?
(19 answers)
Closed 5 years ago.
In Java, why doesn't the following line of code work?
List<List<String>> myList = new ArrayList<ArrayList<String>>();
It works if I change it to
List<ArrayList<String>> myList = new ArrayList<ArrayList<String>>();
At first, I thought maybe you can't have lists of an interface, but I can create a List<Runnable> just fine.
Ideas?
Generic types are more pedantic.
List means List or any sub-type, but <List> means only List. If you want a sub-type you need to have <? extends List>
I suspect you can use
List<List<String>> myList = new ArrayList<List<String>>();
The reason you can't do this is that you can be using a reference to a reference and with an extra level of indirection you have to be careful.
// with one level of indirection its simple.
ArrayList alist = new ArrayList();
List list = aList; // all good
list = new LinkedList(); // alist is still good.
With generics you can have two level of indirection which can give you problems so they are more pedantic to avoid these issues.
// with two levels of indirection
List<ArrayList> alist = new ArrayList<ArrayList>();
List<List> list = (List) alist; // gives you a warning.
list.add(new LinkedList()); // adding a LinkedList into a list of ArrayList!!
System.out.println(alist.get(0)); // runtime error
prints
Exception in thread "main" java.lang.ClassCastException: java.util.LinkedList
cannot be cast to java.util.ArrayList
Lets start with this:
ArrayList<ArrayList<String>> myList = new ArrayList<ArrayList<String>>();
This is creating an ArrayList whose elements are ArrayLists.
Now suppose we could assign that to
List<List<String>> myList2 = myList.
Now, we should be able to do this:
myList2.add(new LinkedList<String>());
But that means we have added a LinkedList to a list whose elements are supposed to be ArrayLists. Ooops!!!
In reality, the assignment of myList to myList2 is not legal ... and that ensures that it is not possible to add the wrong kind of List<String> to the ArrayList<ArrayList<String>> object. (No Peter, it is not just pedantry :-) )
Only the top level collection can be declared as an implementing class, while the nested ones must remain interfaces until you actually create instances:
List<List<String>> rootList = new ArrayList<List<String>>();
and then when you create an element to go in, you make it an implementation:
List<String> nodeList = new ArrayList<String>();
rootList.add(nodeList);
Its comparing Type from left(declaration) side to Type from right(instantiation) side. In Left, your type is List<String> while in right, it's ArrayList<String>. If complaining about the difference.
Please update the right side(instatiation) as List i.e.
List<List<String>> myList = new ArrayList<List<String>>();
This should work fine.
I know this is an old question but I just wanted to share my idea.
Instead of making a List of Lists, I personally just make a List of Type[] (List<Type[]> listArray = new ArrayList<Type[]>();), I generate a separate List of just Type (List<Type> list = new ArrayList<Type>();), then .add(list.toArray()). This way, it's clearer and easier to read than the List of Lists syntax which is confusing.
For example, in a recent project where I had an input file where each line with only a "0" meant a new line in the original (it was an encryption algorithm):
String[] input = getInputContents(inFile);
List<String> currentBuffer = new ArrayList<String>();
List<String[]> buffers = new ArrayList<String[]>();
for(String line : input) {
if(line.equals("0")) {
buffers.add((String[])currentBuffer.toArray());
currentBuffer = new ArrayList<String>();
} else {
currentBuffer.add(line);
}
}
the list<list<string>> l1=new list<list<string>>(); is allowed if the list contains one more list inside the list.
public final class CPanelXMLBuilder extends PanelXMLBuilder {
public CPanelXMLBuilder(AuthenticatedUser pAuthenticatedUser, Map<String, Object> pSessionMap, Map<String, Object> pRequestMap, String pPanelTemplate) throws Exception {
super(pAuthenticatedUser, pSessionMap, pRequestMap, pPanelTemplate, null);
}
public Map<String, Object> buildXMLDocument(List<List<String>> pDetailsList) {
if (pDetailsList.size() == 1) {
List<String> pCustomerDetail = pDetailsList.get(0);
xmlDocument.getRootElement().getChild("E_SHOW1").setText(pCustomerDetail.get(0));
xmlDocument.getRootElement().getChild("E_SHOW2").setText(pCustomerDetail.get(1));
xmlDocument.getRootElement().getChild("E_SHOW3").setText(pCustomerDetail.get(2));
xmlDocument.getRootElement().getChild("E_SHOW4").setText(pCustomerDetail.get(3));
xmlDocument.getRootElement().getChild("E_SHOW5").setText(pCustomerDetail.get(4));
xmlDocument.getRootElement().getChild("ServerTimestamp").setText(pCustomerDetail.get(5).substring(0, 19));
} else {
xmlDocument.getRootElement().getChild("AlertType").setText("INFO");
xmlDocument.getRootElement().getChild("Alert").setText("There is no matching record.");
}
requestMap.put(RequestMapKeys.XML_DOCUMENT, xmlDocument);
return requestMap;
}
}

Deleting a Int from my ArrayList

I have a Arraylist: ArrayList<PlayerBean> playerlist = new ArrayList<PlayerBean>();
from an Object that includes a String and an double (Name and points).
public class PlayerBean{private String name;private double points;}
However for one of my Spinners I want to show only the name (String) in my Arraylist.
How do I manage to delete(remove) the double(points)?
I tried this without any success any ideas?
I am using the swinger for android. any idea?
ArrayList<PlayerBean> playerlist = new ArrayList<PlayerBean>();
List<String> namesOnly = filterNames(playerlist);
private List<String> filterNames(ArrayList<PlayerBean> playerlist12) {
List<String> names = new ArrayList<String>();
for(PlayerBean b : playerlist12)
{
names.add(b.getName());
}
return names;
}
Your list contains PlayerBean objects and you can't temporarily delete member variables from objects. Thus you can't remove points from the list.
You could either use a List<String> instead or provide a spinner model that only displays the name. I assume you're using Swing, don't you?
Rather than removing them, why don't you make a new array List of String type, and assign all the names into this list. So you don't have any points.

Categories