I am trying to sort my list of objects like this:
List<UsersDataFoundTo> mergedUsers = mergeUsersFound(ldapUsers, foundUsers);
return mergedUsers.sort((UsersDataFoundTo h1, UsersDataFoundTo h2) -> h1.getLastName().compareTo(h2.getLastName()));
and on the return statement I get an error:
Incompatible types.
Required: java.util.List<UsersDataFoundTo>
Found:void
What do I do wrong then?
Much easier would be to write is as:
mergedUsers.sort(Comparator.comparing(UsersDataFoundTo::getLastName))
And sort has a void return type, so basically do a :
return mergedUsers;
For reusable, I think the class UsersDataFoundTo should implements Comparable and override compareTo function.
class UsersDataFoundTo implements Comparable<UsersDataFoundTo> {
private String lastNam;
public String getLastNam() {
return lastNam;
}
public void setLastNam(String lastNam) {
this.lastNam = lastNam;
}
#Override
public int compareTo(UsersDataFoundTo other) {
return getLastNam().compareTo(other.getLastNam());
}
}
Then you can use a collection utility to sort it like this:
List<UsersDataFoundTo> mergedUsers = //...
java.util.Collections.sort(mergedUsers);
I hope this help.
Related
Consider following interface:
class SomeParamClass<T> {
public T getT() {return null;}
}
class GetThing<T, TSomeImpl extends SomeParamClass<T>> {
TSomeImpl thingcreator;
GetThing(TSomeImpl thingcreator) {
this.thingcreator = thingcreator;
}
T getThing() {
return thingcreator.get(offset);
}
TSomeImpl getOrigClass() {
return thingcreator;
}
}
This is just an example of a problem that I encountered few times already.
In this example, type T is directly bound to parameter TSomeImpl. If you create it like this:
new GetThing<String,TSomeImpl<String>>(new TSomeImpl<String>())
The parameter String is repeated unnecessarily. It is redundant, but Java seems to require it in this case.
Is there a way to use generic parameters inner parameter as a type?
I made up this syntax, is there a syntax that actually works for this?
// Pseudocode on refering to generic parameter's parameters
class GetThing<TSomeImpl extends SomeParamClass<T>, TSomeImpl::<T>> {
TSomeImpl thingcreator;
GetThing(TSomeImpl thingcreator) {
this.thingcreator = thingcreator;
}
TSomeImpl::<T> getThing() {
return thingcreator.get(offset);
}
TSomeImpl getOrigClass() {
return thingcreator;
}
}
That would be than used just as:
GetThing<TSomeImpl<String>>
No other parameters are necessary.
To clarify: How can I re-write the original class so that it only has one generic argument, List<T> and the T argument is inferred, since it is unambiguously known from List<T>.
what about this
interface SomeType<T> {
T getT();
}
class SomeParamClass<T> implements SomeType<T> {
public T getT() {return null;}
}
class GetThing<T> {
SomeType<T> thingcreator;
GetThing(SomeType<T> thingcreator) {
this.thingcreator = thingcreator;
}
T getThing() {
return thingcreator.getT();
}
SomeType<T> getOrigClass() {
return thingcreator;
}
}
you can use it like this
new GetThing<String>(new SomeParamClass<>());
The problem is that you're trying to use TList as some kind of alias. That's not what generics are for.
Generic type parameters are just that: parameters. There's no way to hide a parameter. They must be explicit.
What's wrong with this? Why doesn't it satisfy your requirements?
class GetListEntry<T>
{
List<T> list;
GetListEntry(List<T> list) {
this.list = list;
}
T getValueAt(int offset) {
return list.get(offset);
}
}
Maybe I do not understand the problem but what is TList for? Looks like a redundant definition. Wouldn't something like this work:
public class ListOfSomething<T> {
private List<T> things;
public ListOfSomething(List<T> things) {
super();
this.things = things;
}
T getValueAt(int offset) {
return this.things.get(offset);
}
}
I would referr to Michaels answer. There does not seem to be an apparent reason for you to mask your list like that. However, if you really want to do it this way, I belive you can do it by just leaving out the generic parameters in your variable declaration. The only place you need to specify this, is the parameters of the constructor. So, just using
GetListEntry test = new GetListEntry(new ArrayList<String>());
should work fine.
You can try my test code on this java online compiler. Thats where I tried it and it works fine.
import java.util.List;
import java.util.ArrayList;
public class MyClass {
public static void main(String args[]) {
ArrayList<String> stringList = new ArrayList<String>();
stringList.add("1");
stringList.add("2");
stringList.add("3");
GetListEntry test = new GetListEntry(stringList);
for(int i = 0; i <= 2; i++)
System.out.println(test.getValueAt(i));
}
static class GetListEntry<T, TList extends List<T>> {
TList list;
GetListEntry(TList list) {
this.list = list;
}
T getValueAt(int offset) {
return list.get(offset);
}
}
}
As you said, the information is redundant. So, the needed information is taken from where its already mentioned. Namely, the ArrayList's generic Type.
Hello I want to do a really simple thing. Just make a template function for any numbers. I actually want as little as ability to "add". In C++ it would be really trivial like this:
template <typename T>
inline T add (T a, T b) {
return a + b;
}
int main(int argc, char** argv){
printf("int: %d\n",add(1,2));
printf("float: %f\n",add(1.1,2.1));
}
In Java I got a tough lesson. I'm new to Java so I believe (and hope) I'm totally wrong and over engineering this. But only thing I come up with was:
public interface IntrfcWowNumbersAdds<T> {
T add(Number v);
}
public class SuperSmartInteger extends Number implements IntrfcWowNumbersAdds<SuperSmartInteger>{
private Integer i;
public SuperSmartInteger(int v) {
i = v;
}
#Override
public String toString(){
return ""+i;
}
#Override
public SuperSmartInteger add(Number v) {
return new SuperSmartInteger(this.intValue()+v.intValue());
}
#Override
public int intValue() {
return i; // thx god for auto(un)boxing
}
#Override
public long longValue() {
return i;
}
#Override
public float floatValue() {
return i;
}
#Override
public double doubleValue() {
return i;
}
}
And note that this crazy wrapper above I would have to do for any number I would like to use template for (eg double, byte etc...)
public class ThreadSafeNum<T extends Number & IntrfcWowNumbersAdds<T>> {
private T num;
public ThreadSafeNum(T n){
num = n;
}
public T add(T v){
// note in here I plan to do some locking...
return num = num.add(v);
}
}
then I can use it as:
SuperSmartInteger i = new SuperSmartInteger(5);
SuperSmartInteger i2 = i.add(6);
System.out.println(""+i2);
ThreadSafeNum<SuperSmartInteger> tsn = new ThreadSafeNum<SuperSmartInteger>(i);
SuperSmartInteger i3 = tsn.add(i2);
I know that when add() would be only adding I can just use + operator and rely on auto(un)boxing. But my add() method is meant to do something extra (like lock).
So how to do it properly? Or is my way correct???
Something like this as the base class:
public abstract class Addable<T extends Number,U extends Addable<T,U>> {
private final T value;
public Addable( final T value ){ this.value = value; }
public T getValue(){ return value; }
public abstract U add( U addend );
}
And this as the sub-class:
public class AddableInteger extends Addable<Integer,AddableInteger> {
public AddableInteger( final Integer value ){
super( value );
}
#Override
public AddableInteger add( final AddableInteger addend ){
java.util.Objects.requireNonNull( addend );
return new AddableInteger( this.getValue() + addend.getValue() );
}
}
Well, the reasons that works in C++ is that the compiler will create as many functions as there are calls in the code, and compile each one independently in order to validate if '+' is a reasonable thing to do in that particular case. This is a little like a case of compiler-assisted duck-typing. In other words, there is no guarantee that type T will have a + operator and only the fact that the compiler will look at the actual call types and create permutations helps you.
Note that there is some risk in letting the compiler "add whatever", since there is no interface or contract that guarantees the semantics to be correct. That is what a class hierarchy brings you.
This is trickier to do in full type safety since inheritance can be complex and the return types need to be somewhat clear. Inheritance is the usual thing so that a virtual method knows how to add its own type, but in this case you can't change the class hierarchy of Number.
You can, nevertheless, do something like this:
public static int addAsInt(Number a, Number b)
{
a.intValue() + b.intValue();
}
And the same for other return types. That will take any two instances of number and generate an output value, assuming which kind of output type you want. Somewhat easier than creating wrapper classes in this particular case.
I have implemented compareTo to allow me to compare my class' based on some criteria and it is working fine.
However, at some point I want to compare the class' on one thing and at another point in the code I want to compare the class based on another thing.
Is it possible to have two different implementations of compareTo and using one at some point and one at another?
In general the mechanism to do this is to implement one or more Comparators and use the appropriate one as needed.
Since your Class is "Comparable" you can use the compareTo, you can't - however - create more then one implementation of that function to be used at different points in the same Class (you have one function to override, and you can't do that twice).
You can, however, take a look at the Comparator Interface; and implementation of that interface can allow you to implement and use a different compareTo for your object.
We achieved something similar by writing a utility comparator for our class - something like this:
public class FooComparator implements Comparator<Foo> {
public static String COMPARE_FIELD1 = "COMPARE_FIELD1";
public static String COMPARE_FIELD2 = "COMPARE_FIELD2";
public static String COMPARE_FIELD3 = "COMPARE_FIELD3";
private String compareBy = COMPARE_FIELD1;
private boolean reverse = true;
public FooComparator(){}
public FooComparator(String sort){
compareBy = sort;
}
public void reverse() {
if(reverse) {reverse = false;
} else {reverse = true;}
}
public void field1Sort() {compareBy = COMPARE_FIELD1;}
public void field2Sort() {compareBy = COMPARE_FIELD2;}
public void field3Sort() {compareBy = COMPARE_FIELD3;}
public int compare(Foo foo1, Foo foo2) {
if(compareBy.equals(COMPARE_FIELD2)) {
return compareByField2(foo1, foo2);
} else if(compareBy.equals(COMPARE_FIELD3)) {
return compareByField3(foo1, foo2);
}
return compareByField1(foo1, foo2);
}
private int compareByField1(Foo foo1, Foo foo2) {
if(reverse) {return foo1.getField1().compareTo(foo2.getField1());}
return foo1.getField1().compareTo(foo2.getField1());
}
private int compareByField2(Foo foo1, Foo foo2) {
if(reverse) {return foo1.getField2().compareTo(foo2.getField2());}
return foo1.getField2().compareTo(foo2.getField2());
}
private int compareByField3(Foo foo1, Foo foo2) {
if(reverse) {return foo1.getField3().compareTo(foo2.getField3());}
return foo1.getField3().compareTo(foo2.getField3());
}
}
We then can use it like this:
List<Foo> foos = new ArrayList<Foo>();
FooComparator comparator = new FooComparator(FooComparator.COMPARE_FIELD1);
Collections.sort(foos, comparator);
I want to compare an array of comparables. The simplest way seems the following (details not shown):
public class ArrayComparable implements Comparable<ArrayComparable>{
ArrayList<Comparable<?>> list = new ArrayList<Comparable<?>>();
#Override
public int compareTo(ArrayComparable ac) {
Iterator<Comparable<?>> itr = ac.list.iterator();
for(Comparable<?> l : list) {
Comparable<?> itrNext = itr.next();
if(itrNext.getClass() == l.getClass()) {
if(itrNext.compareTo(l)) {
//something
} else {
//other stuff
}
} else {
//some other thing
}
}
}
Of course the problem here is that the compareTo as in itrNext.compareTo(l) will not work giving the error: The method compareTo(capture#6-of ?) in the type Comparable<capture#6-of ?> is not applicable for the arguments (Comparable<capture#7-of ?>)
which I understand why (as far as the method is concerned I might be comparing apples to oranges). On the other hand, I know I am not as I check for the class of things before comparing them.
So is there a way I can make this work? Don't worry about the sanity of comparing arrays of any comparables, as I have a good reason why I want to do that.
EDIT- SO why would I want to do something like this. Say I wanted to have an array of comparables, and I didn't care what was contained in each index, as long as the types corresponded, and they could be compared. Then I could do a general lexicographical compare between these arrays. This way I don't have to write a comparable for (int,int) and (int, string), and (string, double, string) or whatever you need. I just write one, and as long as I make sure that the types match (and I can), I am good to go.
Using the raw type Comparable wherever you're currently using Comparable<?> should work. Actually, you could just do that in one place if you want:
if (((Comparable) itrNext).compareTo(l) == 0)
Make ArrayComparable a generic class so that you can properly parameterize the generics rather than using <?> everywhere. Oh, and you might as well implement Iterable as well.
public class ArrayComparable<T> implements Comparable<ArrayComparable<T>>, Iterable<T>
{
List<Comparable<T>> list = new ArrayList<Comparable<T>>();
#Override
public int compareTo(ArrayComparable<T> ac)
{
// snip
}
#Override
public Iterator<T> iterator()
{
return list.iterator();
}
}
Try this:
if(itrNext.getClass().cast(itrNext).compareTo(l.getClass().cast(l))) {
//something
} else {
//other stuff
}
public class GenericDemo<T>{
T g;
public <T extends Comparable<T>> void printData(T a[]){
T max = a[0];
if(a[1].compareTo(max)>0){
max=a[1];
}
if(a[2].compareTo(max)>0){
max=a[1];
}
System.out.println(max);
System.out.println("DataType: " +a.getClass().getName());
}
public static void main(String[] ar)
{
Integer a[]={1,2,3};
Byte b[]= {4,6,7};
Short c[]={6,8,9};
GenericDemo g = new GenericDemo();
g.printData(a);
g.printData(b);
g.printData(c);
}
}
A good answer to this would be:
public final class ArrayComparable<T extends Comparable<T>>
implements Comparable<ArrayComparable<T>> {
private final ArrayList<T> list = new ArrayList<>();
#Override
public int compareTo(final ArrayComparable<T> other) {
final Iterator<T> it = other.list.iterator();
for (final T element : list) {
final T otherElement = it.next();
final int comparison = element.compareTo(otherElement);
if (comparison < 0) {
// something
} else if (comparison > 0) {
// other stuff
} else {
// other stuff
}
}
return 0;
}
}
I'm trying to define a class (or set of classes which implement the same interface) that will behave as a loosely typed object (like JavaScript). They can hold any sort of data and operations on them depend on the underlying type.
I have it working in three different ways but none seem ideal. These test versions only allow strings and integers and the only operation is add. Adding integers results in the sum of the integer values, adding strings concatenates the strings and adding an integer to a string converts the integer to a string and concatenates it with the string. The final version will have more types (Doubles, Arrays, JavaScript-like objects where new properties can be added dynamically) and more operations.
Way 1:
public interface DynObject1 {
#Override public String toString();
public DynObject1 add(DynObject1 d);
public DynObject1 addTo(DynInteger1 d);
public DynObject1 addTo(DynString1 d);
}
public class DynInteger1 implements DynObject1 {
private int value;
public DynInteger1(int v) {
value = v;
}
#Override
public String toString() {
return Integer.toString(value);
}
public DynObject1 add(DynObject1 d) {
return d.addTo(this);
}
public DynObject1 addTo(DynInteger1 d) {
return new DynInteger1(d.value + value);
}
public DynObject1 addTo(DynString1 d)
{
return new DynString1(d.toString()+Integer.toString(value));
}
}
...and similar for DynString1
Way 2:
public interface DynObject2 {
#Override public String toString();
public DynObject2 add(DynObject2 d);
}
public class DynInteger2 implements DynObject2 {
private int value;
public DynInteger2(int v) {
value = v;
}
#Override
public String toString() {
return Integer.toString(value);
}
public DynObject2 add(DynObject2 d) {
Class c = d.getClass();
if(c==DynInteger2.class)
{
return new DynInteger2(value + ((DynInteger2)d).value);
}
else
{
return new DynString2(toString() + d.toString());
}
}
}
...and similar for DynString2
Way 3:
public class DynObject3 {
private enum ObjectType {
Integer,
String
};
Object value;
ObjectType type;
public DynObject3(Integer v) {
value = v;
type = ObjectType.Integer;
}
public DynObject3(String v) {
value = v;
type = ObjectType.String;
}
#Override
public String toString() {
return value.toString();
}
public DynObject3 add(DynObject3 d)
{
if(type==ObjectType.Integer && d.type==ObjectType.Integer)
{
return new DynObject3(Integer.valueOf(((Integer)value).intValue()+((Integer)value).intValue()));
}
else
{
return new DynObject3(value.toString()+d.value.toString());
}
}
}
With the if-else logic I could use value.getClass()==Integer.class instead of storing the type but with more types I'd change this to use a switch statement and Java doesn't allow switch to use Classes.
Anyway... My question is what is the best way to go about something thike this?
What you are trying to do is called double dispatch. You want the method called to depend both on the runtime type of the object it's called on, and on the runtime type of its argument.
Java and other C derivatives support single dispatch only, which is why you need a kludge like the visitor pattern you used in option 1. This is the common way of implementing it. I would prefer this method because it uses no reflection. Furthermore, it allows you to keep each case in its own method, without needing a big "switchboard" method to do the dispatching.
I'd choose the second option, with the third, I'd better be using generics so you don't rely on that Enum. And with the first option you could be implementing methods for the rest of your life. Anyways you could use "instanceof" operator for Class matching.