android - creating generic interface for two List wrappers - java

I have to perform similar methods on two types of lists.
private List<WifiConfiguration> wifiConfigurations;
private List<ScanResult> mScanResults;
I need to scan both lists and look for some specific item, so I figured I'll create an interface to wrap them up, and then implement each doesListContains method.
public interface IWifiListWrapper {
boolean doesListContains(IWifiInfo wifiInfo);
// <T> void setList(List<T> wifiList);
}
And one implementation for example is:
public class ScanResultsListWrapper implements IWifiListWrapper {
private List<ScanResult> mScanResults;
#Override
public boolean doesListContains(IWifiInfo wifiInfo) {
...
}
}
That's all good.
Now, I also need to have a setList method to set the list in each of the implementations to their specific List types (WifiConfiguration and ScanResult).
It looks like is should be implemented with Generics somehow, but I am not really sure How do I do it.. I do need to somehow declare each list in the beginning with its Type, correct? so I can pass a matching List type.
How should I go about it?

public interface IWifiListWrapper<T> {
boolean doesListContains(IWifiInfo wifiInfo);
void setList(List<T> wifiList);
}
You can also add restrictions to type like T extends WifiInfo.
public class ScanResultsListWrapper implements IWifiListWrapper<ScanResult> {
private List<ScanResult> mScanResults;
#Override
public boolean doesListContains(IWifiInfo wifiInfo) {
...
}
#Override
public void setList(List<ScanResult> wifiList) {
...
}
}

Related

Collections.sort on List<Interface> when implementer classes have their own compareTo

I've interface MyInterface and two classes ( Summary, Detail) are implementing this, and overriding compareTo.
A third class DetailMe is extending Detail
Another class (MyApi) is using List<MyInterface> , and complaining for Collections.sort , what am i doing wrong ?
public class Summmary implements MyInterface, Comparable<Summary> {
private Detail detail;
public Summary(Detail detail) {
this.detail = detail;
}
// properties
// methods
#Override
public int compareTo(Summary o) {
// Do work
}
}
==
public class Detail implements MyInterface, Comparable<Detail> {
// properties
// methods
#Override
public int compareTo(Detail o) {
// Do Detail work
}
}
==
public class DetailMe extends Detail {
// Do work
}
==
public class MyApi {
private List<MyInterface> myList;
public MyApi(List<MyInterface> myList) {
this.myList = myList
Collections.sort(this.myList); // COMPLIATION ERROR
}
}
You need to ensure (in a way the compiler knows of) that the list only contains one type of object, because your objects can't compare with each other.
So, your list must be either a List<Summmary> or a List<Detail>.
That is, unless you define the ordering of mixed elements, but then both classes would have to implement public int compareTo(MyInterface o).

Java - Handling generics with inheritance

I have a class that represents a vendor service and all their services have an authentication and an execute method.
I started thiking of an abstract class that represents this as below.
The thing is each of their services require a different request object, so I thought of using generics.
The problem is that if use it, I can't handle the specifics of each request object. Each children must use some methods from the type.
1) Should I try to make this way I'm trying, or remove this executeRequest method from the abstract class and each subclass implement it with the correct type?
2) I always hear "prefer composition over inheritance". Should I move the executeRequest to an interface?
Thanks in advance!
public abstract class VendorService {
private final VendorInitialization VendorInitialization;
//a bean with some auth params
public VendorService(VendorInitialization VendorInitialization) {
this.VendorInitialization = VendorInitialization;
}
protected abstract <T> boolean validateRequest(T requestObject) throws VendorServiceBadRequest;
protected abstract <T, P> P executeRequest(T requestObject);
}
public class VendorServiceAllocation extends VendorService {
public VendorServiceAllocation(VendorInitialization VendorInitialization) {
super(VendorInitialization);
}
#Override
protected <T> boolean validateRequest(T requestObject) throws VendorServiceBadRequest {
//List<BeanAllocation> requestObject = new Arraylist<>(); //I was using like this before
//TODO: how to handle it as list of on this specific case?
if (requestObject == null || requestObject.size() == 0) {
throw new VendorServiceBadRequest(String.format("The list must have at least one element"));
}
//TODO: requestObject.get(0).getMySpecificFieldFromBeanAllocation will not work
//some checks
return true;
}
#Override
protected <T, P> P executeRequest(T requestObject) {
//executes and return a list of objects specific to this class
return new List<BeanAllocationResponse>();
}
}
Edit, for clarification:
In the child class VendorServiceAllocation, I need to use some methods that are specific of that type.
E.g.: Inside executeRequest, I need to call requestObject.customFunctionFromChild()
I think niceman hit the nail on the head, though I am not quite sure what you are asking. eg.
abstract class Service<T,P>{
abstract public P processRequest(T t);
}
Then you can implement it in one of two ways.
class StringService extends Service<String, String>{
public String processRequest(String t){
return t;
}
}
Or you could leave it to still be Generic and the actual instances would have the different types.
class OtherService<T> extends Service<T, String>{
public String processRequest(T t){
return t.toString();
}
}
Where you could use it as,
OtherService<Integer> is = new OtherService<>();

Use instanceof or public method to get instance

So I have 3 classes:
Item
GroupItem extends Item
ProductItem extends Item
I am passing a array of Item objects to a class and want to do separate things depending on their class type.
Would using instanceof be an acceptable way of doing this or should I have an internal boolean isGroup() method which will be set on initialisation of the specified sub-class.
class Item {
protected boolean isGroup = false;
public boolean isGroupItem() { return isGroup; }
}
class GroupItem extends Item {
public GroupItem() {
isGroup = true;
}
}
class ProductItem extends Item {
public ProductItem() {
isGroup = false;
}
}
class Promotion {
// Item can be either a group or a list of items
private List<Item> items = new LinkedList<Item>;
public void addItem(Item itemObj) {
items.addItem(itemObj);
}
public List<Item> getItems() {
return items;
}
}
class Checker {
// Items retrieved from Promotion and passed from another class as array
public Checker(Item[] items) {
// either
if(items[0] instanceof GroupItem) {
// Do something ...
}
// or
if(items[0].isGroupItem()) {
// Do something ...
}
}
}
So my questions are:
instanceof or method?
if method, in Item or Promotion?
and, Why? (Just so i can better understand the reasoning)
Thanks in advance
Use different methods on the actual type you want to pass as parameter.
Usually, using instance of means that there is something wrong in your model.
If you need to have different behaviors for different subtypes, it means that you are not really using the parent type. In addition, you are compelled to know the implementation details, which should not be the case.
If the inheritance you have is only a technical one, try to use composition instead of inheritance.
This is the exact place where you should use instanceOf operator .
The instanceof operator compares an object to a specified type. You
can use it to test if an object is an instance of a class, an instance
of a subclass, or an instance of a class that implements a particular
interface.
There is no point to skatch a new method or some boolean property to do this stuff. You can easily identify specific Object of GroupItem by check instanceOf.
you can also use GroupItem.class.isInstance(items[0]) to check the same. like -
if(GroupItem.class.isInstance(items[0])) {
// Do something ...
}
I guess I would try to define why I need to know if it is a group at this point.
Let's say it is to decide if one Item is eligible for a promotion and the promotion rules might change: then I would use instanceof, because you don't want the promotion rules logic to "pollute" your basic objects.
If being a group is an important property of your item and is useful in various contexts (not just the promotion rules), I would include it at the Item level.
The instaceOf operator is a better choice but I would also consider to use the Visitor pattern.
interface Item{
void accept(CheckerVisitor checker);
}
class GroupItem implements Item{
void accept(CheckerVisitor checker){
checker.visit(this);
}
}
class OtherItem implements Item{
void accept(CheckerVisitor checker){
checker.visit(this);
}
}
class CheckerVisitor{
void visit(GroupItem groupItem){
//do specific things to GroupItem
}
void visit(OtherItem otherItem){}
}
class MyClassOfItems{
List<Item> items = ...;
for(Item item : items){
item.accept(new CheckerVisitor());
}
}
So after reading this i chose a different path for my solution. Thanks for everyone who helped.
The solution I chose allows me to not even be bothered with what sub-type the object is (thanks to Assylias and Balázs Mária Németh for making me rethink my structure) as I use abstract classes to just get the information i need.
abstract class Item {
public Item(...) {
initialise();
createSQLSegment();
}
protected String SQLSegment = "";
protected abstract void createSQLSegment();
public String getSQLSegment() {
return SQLSegment;
}
...
}
// Concrete class creates response
class GroupItem extends Item {
...
// Concrete method
protected void createSQLStatement() {
SQLStatement = "...SQL...";
}
}
class ProductItem extends Item {
...
// Concrete method
protected void createSQLSegment() {
SQLSegment = "...SQL..."
}
}
class Promotion {
// Item can be either a group or a list of items? extends Item>;
public void addItem(Item itemObj) {
items.addItem(itemObj);
}
public List<Item> getItems() {
return items;
}
}
class Checker {
// Items retrieved from Promotion and passed from another class as array
public Checker(Item[] items) {
...
for(Item item : Items) {
addPreparedSQLToBatch(item);
}
}
private void addPreparedItemToBatch(Item item) {
...
// No need to know concrete class
SQLString += Item.getSQLSegment();
...
}
}
Thanks again to everyone.
Comments welcome, I'm always learning :-)

Create list with different objects

I have a method that takes in a List<> and adds all the numbers in the list together and returns if the number is = 100
My problem is that I want to use the same method for a number of different types of lists
So instead of having this
public boolean checkPercent(List<BarStaff> associates){..same..}
public boolean checkPercent(List<Waiters> associates){..same..}
public boolean checkPercent(List<KitchenStaff> associates){..same..}
I want to have this
public boolean checkPercent(List<could be any type> associates){..same..}
Instead of reusing the same code just of different lists, is there a way to use the same code for all the different types of lists (the staff have the same values in them so they are not different in any way)?
You could use a parameterized method:
public <T> boolean checkPercent(List<T> associates)
{
// snip...
}
or just accept any list:
public boolean checkPercent(List<?> associates)
{
// snip...
}
You may create a generic method:
public <T> boolean checkPercent(List<T> associates) {
... your code ...
}
Use generics:
public <T> boolean checkPercent(List<T> associates){...}
The object-oriented approach would be to have BarStaff, Waiters, and KitchenStaff implement a Employee interface that has a method public int getPercentage().
public boolean checkPercent(List<? extends Employee> associates)
{
foreach (Employee associate in associates)
{
int i = associate.getPercentage();
// rest of code.
}
}

Force a generic type to be an interface?

It looks like this is impossible to do, but does anyone have a clever way around this problem?
public class SomeClassIterableWrapper<S, T extends SomeClass & S> implements Iterable<S>
Where S is supposed to be an interface of some unknown type and SomeClass is a 2D array with a row index, similar in functionality to a bidirectional JDBC resultset. Subclasses of SomeClass have custom getters and setters for each column. I want to be able to iterate through this structure like I would a List. I want to implement a common interface between my SomeClass and Bean to have access to the getters and setters. As such S needs to be that interface. However the declaration I provided does not work. Is there a way to work around this?
edit to show my desired implementation:
public class SomeClassIterableWrapper<S, T extends SomeClass & S> implements Iterable<S>{
T object;
public SomeClassWrapper(T object){
this.object = object;
}
#Override
public Iterator<S> iterator() {
object.setIndex(-1);
return new SomeClassIterator<S>();
}
private class SomeClassIterator<S> implements Iterator<S> {
#Override
public boolean hasNext() {
return object.index() < object.rowSize() - 1;
}
#Override
public S next() {
object.next();
//safe because only interface methods allowed, can't further manipulate index
return object;
}
#Override
public void remove() {
object.deleteRow();
}
}
Can't you parameterize SomeClass with S? Then you could have
public class SomeClassIterableWrapper<S, T extends SomeClass<S>>
implements Iterable<S>{
I think the S in extends SomeClass & S
public class SomeClassIterableWrapper
has to be a definite class because in this context,
S has to be a class that is extending something.
Is there a way you can narrow down what the
potential classes that are used in place of S are?
You could use multiple ampersands if you have multiple
classes that T should extend
I confess that I don't fully comprehend the problem but this is what I suggest:
Create an interface of S. It contains one method ad it returns the S object.
public interface SWrapper<S> {
S getS();
}
Then create an implementation:
public class SImpl implements SWrapper<SImpl> {
#Override
public SImpl getS() {
return this;
}
}
You can now create:
public class SomeClass<T extends SomeClass & SWrapper<T>> {
private final T object;
public SomeClass(T object) {
this.object = object;
}
}
You will have to modify your usage a bit but perhaps it works.

Categories