The exception is in the ListCreator i 'when' method line with adding t
Do you guys can maybe tell me why I get this exception? Intelij doesnt see any mistakes in syntax and logic so whats the problem?
I wanted to make my own mapper and selector (filter) and i get this all the time. Is anything wrong here?
Can you please see what might cause this?
I need to use generics and I get lost with those.
package zad1;
import java.util.*;
public class ListCreator<T> {// Uwaga: klasa musi być sparametrtyzowana
List<T> list;
protected ListCreator(List<T> listcreate){
this.list = listcreate; //kreator robi nowa liste zeby nie modyfikowac
}
public static <T> ListCreator<T> collectFrom(List<T> srclist){
ListCreator<T> listCreator = new ListCreator<>(srclist);
return listCreator;
}
public ListCreator<T> when(Selector<T> selector){
List<T> nextlist = new ArrayList<>();
for (T t: this.list){
if (selector.select(t)){
this.list.add(t); //dla kazdego elementu list ktoremu kolejno odpowiada t, jesli spelnia warunek to element jest dodawany do nowej listy
}
}
this.list = nextlist;
return this;
}
public <S> List<S> mapEvery(Mapper<T,S> map){
List<S> dlist = new ArrayList<>();
for (T arg: this.list){
dlist.add(map.map(arg));
}
return dlist;
}
}
package zad1;
import java.util.*;
public class Main {
public Main() {
List<Integer> src1 = Arrays.asList(1,7,9,11,12);
System.out.println(test1(src1));
List<String> src2 = Arrays.asList("a", "zzzz", "vvvvvvv");
System.out.println(test2(src2));
}
public List<Integer> test1(List<Integer> src) {
Selector <Integer> sel = new Selector<Integer>() {
#Override
public boolean select(Integer arg) {
return arg < 10;
}
};
Mapper <Integer,Integer> map = new Mapper<Integer, Integer>() {
#Override
public Integer map(Integer arg) {
return arg + 10;
}
};
return ListCreator.collectFrom(src).when(sel).mapEvery(map);
}
public List<Integer> test2(List<String> src) {
Selector <String> sel = new Selector<String>() {
#Override
public boolean select(String arg) {
if (arg.length() > 3)
return true;
else
return false;
}
};
Mapper <String, Integer> map = new Mapper<String, Integer>() {
#Override
public Integer map(String arg) {
return arg.length() + 10;
}
};
return ListCreator.collectFrom(src).when(sel).mapEvery(map);
}
public static void main(String[] args) {
new Main();
}
}
Related
We have a Liststack and an ADTStackJqwikTest.
Here's my code in ListStack for the push and the pushAll() method.
#Override
public Stack<A> push(A e) {
return new ListStack(list.cons(e));
}
#Override
public Stack<A> pushAll(List<A> xs) {
return xs.isEmpty() ? this : new ListStack<A>(List.append(xs, list));
}
In my ListStack I've a test:
public static void main(String[] args) {
Stack<Integer> s1 = empty();
s1 = s1.pushAll(list(1,2,3));
s1 = s1.pushAll(list(1,2,3));
System.out.println("PushAll: " + s1.toList());
Stack<Integer> s2 = empty();
s2 = s2.push(1);
s2 = s2.push(2);
s2 = s2.push(3);
s2 = s2.push(1);
s2 = s2.push(2);
s2 = s2.push(3);
System.out.println("Push: " + s2.toList());
}
}
the result I get is:
PushAll: 1, 2, 3, 1, 2, 3
Push: 3, 2, 1, 3, 2, 1
But the result should be the same. What do I wrong?
In my ADTStackJqwikTest I've to pushAll() methods.
// ∀s:Stack<A> : pushAll([],s) = s
#Property
<A> boolean pushAll(#ForAll("stacks") Stack<A> s) {
return s.pushAll(List.list()).equals(s);
}
// ∀s:Stack<A>, ∀xs:List<A> : pushAll(x:xs,s)= push(x,pushAll(xs,s)), falls s nicht leer
#Property
<A> boolean pushAll(#ForAll("stacks") Stack<A> s, #ForAll("lists") List<A> xs, #ForAll("as") A x) {
return s.pushAll(xs.cons(x)).equals(s.push(x).pushAll(xs));
}
package stack;
import list.List;
import tuple.Tuple;
import static list.List.list;
public class ListStack implements Stack {
private final List<A> list;
private ListStack(List<A> list) {
this.list = list;
}
private ListStack() {
this.list = list();
}
#Override
public boolean isEmpty() {
return list.isEmpty();
}
#Override
public Stack<A> push(A e) {
return new ListStack<A>(list.cons(e));
}
#Override
public Stack<A> pop() {
if(isEmpty())
throw new IllegalStateException("pop from an empty stack");
else return new ListStack<A>(list.tail());
}
#Override
public A top() {
if(isEmpty())
throw new IllegalStateException("top from an empty stack");
else return list.head();
}
#Override
public Tuple<A, Stack<A>> popTop() {
return Tuple.tuple(top(), pop());
}
#Override
public Tuple<List<A>, Stack<A>> popTopAll() {
return null;
}
#Override
public Stack<A> pushAll(List<A> xs) {
return xs.isEmpty() ? this : new ListStack<A>(List.append(xs, list));
}
#Override
public List<A> toList() {
return list;
}
#Override
public boolean isEqualTo(Stack<A> s) {
return this.toList().isEqualTo(s.toList());
}
#Override
public boolean equals(Object o) {
return o instanceof Stack && isEqualTo((Stack) o);
}
public String toString() {
return list.toString();
}
public static <A> Stack<A> empty() {
return new ListStack(list());
}
This is my whole ListStack
change
#Override
public Stack<A> pushAll(List<A> xs) {
return xs.isEmpty() ? this : new ListStack<A>(List.append(xs, list));
}
into
#Override
public Stack<A> pushAll(List<A> xs) {
return xs.isEmpty() ? this : new ListStack<A>(List.append(list, xs));
}
Okay I got it. Thank you guys.
The mistake was the append in the pushAll method.
This question already has answers here:
Static method invocation
(5 answers)
Can I call a static method of another class without using the class name?
(3 answers)
Closed 4 years ago.
I have an issue with this code. It throws a "The method collectFrom(List < Integer> ) is undefined for the type Main" error, and I don't really know where's the problem.
The selector from "test1" method should choose from the list numbers lesser than 10, and mapper should increase those chosen numbers by 10.
import java.util.*;
public class Main {
public Main() {
List<Integer> src1 = Arrays.asList(1, 7, 9, 11, 12);
System.out.println(test1(src1));
}
public List<Integer> test1(List<Integer> src) {
Selector<Integer> sel = new Selector<Integer>() {
#Override
public boolean select(Integer a) {
if(a < 10) {
return true;
} else {
return false;
}
}
};
Mapper<Integer> map = new Mapper<Integer>() {
#Override
public Integer map(Integer a) {
return a+=10;
}
};
return collectFrom(src).when(sel).mapEvery(map);
}
public static void main(String[] args) {
new Main();
}
}
And this is my class ListCreator:
import java.util.ArrayList;
import java.util.List;
public class ListCreator <T>{
List<T> lista;
private ListCreator(List<T> src) {
this.lista = src;
}
public static <T> ListCreator<T> collectFrom(List<T> src) {
ListCreator<T> ls = new ListCreator<T>(src);
return ls;
};
public ListCreator<T> when(Selector s) {
List<T> whenLista = new ArrayList<T>();
for(int i = 0; i < lista.size(); ++i) {
if(s.select(lista.get(i))) {
whenLista.add(lista.get(i));
}
}
this.lista = whenLista;
return this;
};
public List<Integer> mapEvery (Mapper m) {
List<Integer> mapLista = new ArrayList<Integer>();
for(int i = 0; i < lista.size(); ++i) {
mapLista.add((Integer)m.map(lista.get(i)));
}
return mapLista;
}
}
Selector and Mapper are just simple, parameterized interfaces.
collectFrom is a static method defined in theListCreatorclass, not inMain`. You could qualify the call:
return ListCreator.collectFrom(src).when(sel).mapEvery(map);
Or just statically import it:
import static mypackage.ListCreator.collectFrom;
I have a problem with the initialization of a List . The Class of the Items isn't known at compile time - they could be int, float, string or custom classes.
So I tried this:
public class Sensordevice {
private List<?> valueList;
public void setValueList(List<?> valueList) {
this.valueList = valueList;
}
public void addValue(Object value) {
if(valueList == null){
valueList = getList(value.getClass());
}
valueList.add(value);
}
private <T> List<T> getList(Class<T> requiredType) {
return new ArrayList<T>();
}
}
But I get this Error at valueList.add(value) in the addValue Methode:
The method add(capture#4-of ?) in the type List is not applicable for the arguments (Object)
Update
Thanks a lot for your replies. This solution works for my.
public class Sensordevice<T> {
private List<T> valueList;
public void setValueList(List<T> valueList) {
this.valueList = valueList;
}
public void addValue(T value) {
if(valueList == null){
valueList = new ArrayList<T>();
}
valueList.add(value);
}
}
This works for me. And by "works" I mean I don't get any errors. It doesn't seem to provide any functionality since there isn't any way to get the list of objects from the Sensordevice since getList just returns a new, empty list, but that's the code you gave. I think the core of the error is having addValue take Object instead of T.
public class Sensordevice {
private List valueList;
public <T> void setValueList(List<T> valueList) {
this.valueList = valueList;
}
public <T> void addValue(T value) {
if(valueList == null){
valueList = getList(value.getClass());
}
valueList.add(value);
}
private <T> List<T> getList(Class<T> requiredType) {
return new ArrayList<>();
}
}
public static void main(String[] args) {
Sensordevice sd = new Sensordevice();
sd.addValue(new Object());
sd.addValue(new Integer(3));
sd.addValue("");
sd.addValue(new Sensordevice());
System.out.println(sd.getList(Sensordevice.class));
}
So if you don't know particular type would you class use, make your class generic:
public class Sensordevice<T> {
private List<T> valueList;
public void setValueList(List<T> valueList) {
this.valueList = valueList;
}
public void addValue(T value) {
if(valueList == null){
valueList = getList(value.getClass());
}
valueList.add(value);
}
private List<T> getList() {
return new ArrayList<T>();
}
}
If you don't know the List type you can leave it without any type specification, just put: private List valueList;
Change the valueList to: private List valueList; and getList() to:
private <T> List<Object> getList(Class<T> requiredType) {
return new ArrayList<Object>();
}
This fixes the error and it appears to work properly.
I tested it with strings, floats, and ints.
To be precise, I am trying to flatten a tree and I am stuck on trying to get the values of private attributes in a generic class using a generic function.
I have attached the classes to show how the tree is structured exactly. But it's looks something like this:
/|\
1 | 6
/|\
5 4 9
I am going to paste my attempt at the end. First, let me introduce the classes:
Triple simply stores three values of the same type.
public class Triple<V> {
private final V l, m, r;
public Triple(V l, V m, V r) {
this.l = l;
this.m = m;
this.r = r;
}
public V left() { return l; }
public V middle() { return m; }
public V right() { return r; }
}
Straightforward interface:
public interface Function<P, R> {
R apply(P p);
}
Now, for a tricky class. This one is simply a type that stores one of EitherOr of two types of value, but not both.
public class EitherOr<A,B> {
// Constructs a left-type EitherOr
public static <A> EitherOr left(A a) {
return new EitherOr(a, null);
}
// Constructs a right-type EitherOr
public static <B> EitherOr right(B b) {
return new EitherOr(null, b);
}
private final A a;
private final B b;
private EitherOr(A a, B b) {
this.a = a; this.b = b;
}
public<T> T ifLeft(Function<A,T> f) {
return f.apply(a);
}
public<T> T ifRight(Function<B,T> f) {
return f.apply(b);
}
public boolean isLeft() {
return b == null;
}
}
I know this is getting long, but bear with me. This class implements the tree structure.
public interface Tree<T> {
EitherOr<T, Triple<Tree<T>>> get();
static final class Leaf<T> implements Tree<T> {
public static <T> Leaf<T> leaf (T value) {
return new Leaf<T>(value);
}
private final T t;
public Leaf(T t) { this.t = t; }
#Override
public EitherOr<T, Triple<Tree<T>>> get() {
return EitherOr.left(t);
}
}
static final class Node<T> implements Tree<T> {
public static <T> Tree<T> tree (T left, T middle, T right) {
return new Node<T>(Leaf.leaf(left), Leaf.leaf(middle), Leaf.leaf(right));
}
private final Triple<Tree<T>> branches;
public Node(Tree<T> left, Tree<T> middle, Tree<T> right) {
this.branches = new Triple<Tree<T>>(left, middle, right);
}
#Override
public EitherOr<T, Triple<Tree<T>>> get() {
return EitherOr.right(branches);
}
}
}
Alright. Here is my idea for flattening:
public class MyFlattenTree<T> implements FlattenTree<T> {
public List<T> flattenInOrder(Tree<T> tree) {
List<T> list = new ArrayList<T>();
EitherOr<T, Triple<Tree<T>>> EitherOr;
EitherOr = tree.get();
// it is a leaf
if (EitherOr.isLeft()) {
// This is where the problem lies
// I don't how to get the value using a function f
list.add((T) EitherOr.ifLeft(f));
return list;
}
else {
// basically recursively go through the tree somehow
}
return null;
}
}
As I said, I am stuck with trying to retreive the value in the EitherOr class using the Function interface. I am thinking of implementing the Function interface and write a function for "apply" that just gets the value, but I am not sure how to do that. Any help would be appreciated. Thanks!
So, here is your flattenInOrder method:
public List<T> flattenInOrder(final Tree<T> tree) {
final EitherOr<T, Triple<Tree<T>>> EitherOr = tree.get();
if (EitherOr.isLeft()) {
return Collections.singletonList(EitherOr.ifLeft(this.ifLeftFunction));
}
return EitherOr.ifRight(this.ifRightFunction);
}
Quite simple, assuming that:
ifLeftFunction yields a single element (since EitherOr<T, Triple<Tree<T>>> has a single T elem' if it s "left")
... and:
ifRightFunction yields a collection of elements (since EitherOr<T, Triple<Tree<T>>> has a list of T elems' if it is "right")
Let's look into these functions now:
ifLeftFunction is... basic. I want to extract a T from... a T.
final Function<T, T> ifLeftFunction = new Function<T, T>() {
#Override
public T apply(final T t) {
return t;
}
};
ifRightFunction is slightly more complex: it has to be recursive and collect all Ts from the Tree it's browsing:
final Function<Triple<Tree<T>>, List<T>> ifRightFunction = new Function<Triple<Tree<T>>, List<T>>() {
#Override
public List<T> apply(final Triple<Tree<T>> t) {
final List<T> res = new ArrayList<>();
res.addAll(MyFlattenTree.this.flattenInOrder(t.left()));
res.addAll(MyFlattenTree.this.flattenInOrder(t.middle()));
res.addAll(MyFlattenTree.this.flattenInOrder(t.right()));
return res;
}
};
And... you're done!
Sample working code:
public class MyFlattenTree<T> {
private final Function<Triple<Tree<T>>, List<T>> ifRightFunction = new Function<Triple<Tree<T>>, List<T>>() {
#Override
public List<T> apply(final Triple<Tree<T>> t) {
final List<T> res = new ArrayList<>();
res.addAll(MyFlattenTree.this.flattenInOrder(t.left()));
res.addAll(MyFlattenTree.this.flattenInOrder(t.middle()));
res.addAll(MyFlattenTree.this.flattenInOrder(t.right()));
return res;
}
};
private final Function<T, T> ifLeftFunction = new Function<T, T>() {
#Override
public T apply(final T t) {
return t;
}
};
public static void main(final String[] args) {
final Tree<String> tree = new Node<>(new Leaf<>("1"), new Node<>(new Leaf<>("5"), new Leaf<>("4"), new Leaf<>("9")), new Leaf<>("6"));
System.out.println(new MyFlattenTree<String>().flattenInOrder(tree));
}
public List<T> flattenInOrder(final Tree<T> tree) {
final EitherOr<T, Triple<Tree<T>>> EitherOr = tree.get();
if (EitherOr.isLeft()) {
return Collections.singletonList(EitherOr.ifLeft(this.ifLeftFunction));
}
return EitherOr.ifRight(this.ifRightFunction);
}
}
Note that I'm creating the exact Tree you're featuring as an example in your question in the main method here:
public static void main(final String[] args) {
final Tree<String> tree = new Node<>(new Leaf<>("1"), new Node<>(new Leaf<>("5"), new Leaf<>("4"), new Leaf<>("9")), new Leaf<>("6"));
System.out.println(new MyFlattenTree<String>().flattenInOrder(tree));
}
Output: [1, 5, 4, 9, 6]
Cheers ;)
Why does following code not throws exception?
import java.util.ArrayList;
import java.util.List;
#SuppressWarnings("unchecked")
public class MainRunner {
public static void main(String[] args) {
List<String> s = new ArrayList<String>() {
{
add("a");
add("1");
add("1");
}
};
// List<Integer> i = (List<Integer>) listConvertor(s, new Integer("1"));
List<Integer> i = (List<Integer>) listConvertor(s, Integer.class);
System.out.println(i);
}
#SuppressWarnings("unchecked")
public static <T, P> List<?> listConvertor(List<T> inputList, P outputClass) {
List<P> outputList = new ArrayList<P>(inputList.size());
for (T t : inputList) {
outputList.add((P) t); // shouldn't be classCastException here?
}
return outputList;
}
}
I want to return List<P> instead of List<?> . But when I write List<P> , it means List<Class<P>> . i.e. in above case , it means List<Class<Integer>> , but I want List<Integer> as return.
I want below code: (so that i don't have to cast again at when method returns)
List<Integer> i = listConvertor(s, Integer.class);
System.out.println(i);
}
#SuppressWarnings("unchecked")
public static <T, P> List<P> listConvertor(List<T> inputList, P outputClass) {
List<P> outputList = new ArrayList<P>(inputList.size());
for (T t : inputList) {
outputList.add((P) t); // shouldn't be classCastException here?
}
return outputList;
}
}
This should do the job with minimal fuss:
public static <T, P> List<P> listConvertor(List<T> inputList, Class<P> outputClass) {
List<P> outputList = new ArrayList<P>(inputList.size());
for (T t : inputList) {
if( !outputClass.isInstance(t) )
throw new ClassCastException("Faked CCException");
#SuppressWarnings("unchecked")
P p = (P) t;
outputList.add(p);
}
return outputList;
}
no cast on the caller side
exception if inappropriate types are in the source list.
public static <T, P> List<P> listConvertor(List<T> inputList, Class<P> outputClass) {
remember, you are passing a Class Object, not an Integer Object.
No, of course it does not throw an exception. Generics are for compile time checks, not run-time. At run time, all your lists are List<Object> and the cast is made implicitly by the JVM.
Edit : in your code,
for (T t : inputList) {
outputList.add((P) t); // shouldn't be classCastException here?
}
is actually compiled to
for (Object t : inputList) {
outputList.add((Object) t); // shouldn't be classCastException here? -- no
}
For example, with your code, if you do i.get(0).getClass() you will then get a ClassCastException as the item cannot be converted from String to Integer.class (note: the same would apply however you do it as you cannot implicitly cast a String to an Integer. Period.)
If this is really what you want to do, cast T to P (for example, cast strings to a numeric value), then I suggest you use another pattern. For example :
static interface ClassConverter<F,T> {
public T convert(F o);
}
static class StringToIntConverter implements ClassConverter<String,Integer> {
public Integer convert(String o) {
try {
return Integer.parseInt(o);
} catch (NumberFormatException e) {
return 0;
}
}
}
public static void main(String[] args) {
List<String> s = new ArrayList<String>() {
{
add("a");
add("1");
add("1");
}
};
// List<Integer> i = (List<Integer>) listConvertor(s, new Integer("1"));
List<Integer> i = (List<Integer>) listConvertor(s, new StringToIntConverter());
System.out.println(i);
System.out.println(i.get(0).getClass().getName());
}
public static <T, P> List<P> listConvertor(List<T> inputList, ClassConverter<T, P> c) {
List<P> outputList = new ArrayList<P>(inputList.size());
for (T t : inputList) {
outputList.add(c.convert(t)); // cast handled by the class method == safer
}
return outputList;
}
Than all you need to do is implement the ClassConverter interface to any types you wish to covert T to P and pass it to your listConverter method.
import java.util.ArrayList;
import java.util.List;
public class MainRunner {
public static void main(String[] args) {
List<String> s = new ArrayList<String>() {
{
add("a");
add("1");
add("1");
}
};
List<Integer> i = listConvertor(s, Integer.class);
System.out.println(i);
}
public static <T, P> List<P> listConvertor(List<T> inputList, Class<P> outputClass) {
List<P> outputList = new ArrayList<P>(inputList.size());
for (T t : inputList) {
outputList.add((P) t); // shouldn't be classCastException here?
}
return outputList;
}
}
Same as #A.H.'s answer, but much simplified using Class.cast(), and also got rid of the unnecessary T:
public static <P> List<P> listConvertor(List<?> inputList, Class<P> outputClass) {
List<P> outputList = new ArrayList<P>(inputList.size());
for (Object t : inputList) {
P p = outputClass.cast(t);
outputList.add(p);
}
return outputList;
}