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.
}
}
Related
A lot of times I find myself (what appears to be) combining composition and inheritance when inheriting from abstract collection classes and I can't help but feel like it's technically conflicting design paradigms while I do it.
/** Custom String List implementation */
public class MyStringList extends AbstractList<String>
{
private final AbstractList<String> _myStringList;
public MyStringList()
{
this._myStringList = new ArrayList<String>();
}
public MyStringList(Collection<String> stringCollection)
{
if (stringCollection.contains(null))
{
throw new NullPointerException("Null values not permitted in MyStringList");
}
else
{
this._myStringList = new ArrayList<String>(stringCollection);
}
}
#Override
public String get(int index)
{
return this._myStringList.get(index);
}
#Override
public int size()
{
return this._myStringList.size();
}
#Override
public String set(int index, String aString)
{
++this.modCount;
return this._myStringList.set(index, Objects.requireNonNull(aString));
}
#Override
public void add(int index, String aString)
{
++this.modCount;
this._myStringList.add(index, Objects.requireNonNull(aString));
}
#Override
public boolean add(String aString)
{
++this.modCount;
return this._myStringList.add(Objects.requireNonNull(aString));
}
#Override
public String remove(int index)
{
++this.modCount;
return this._myStringList.remove(index);
}
// Method to make this list implementation distinct from ArrayList for the sake of
// this StackOverflow question example
public String[] getNumericContaining()
{
return this._myStringList.stream()
.filter(aString -> aString.codePoints().anyMatch(Character::isDigit))
.toArray(String[]::new);
}
// Another method to make this list implementation distinct from ArrayList for
// the sake of this StackOverflow question example
public String[] getUpperCaseContaining()
{
return this._myStringList.stream()
.filter(aString -> aString.codePoints().anyMatch(Character::isUpperCase))
.toArray(String[]::new);
}
}
Is this design of having an internal abstract collection object being the backing object (composition) of the class this object inherits from (inheritance) considered the "correct" way of leveraging the various abstract collection classes defined in the java.util package?
You're combining things unnecessarily. If you want to have what you have in the example, go with Lino's suggestion:
public class MyStringList extends ArrayList<String> {
public String[] getNumericContaining() {
return this.stream()
.filter(aString -> aString.codePoints().anyMatch(Character::isDigit))
.toArray(String[]::new);
}
public String[] getUpperCaseContaining() {
return this.stream()
.filter(aString -> aString.codePoints().anyMatch(Character::isUpperCase))
.toArray(String[]::new);
}
}
however many times a regular List<String> is all you need, since you can extract extra behaviour to the class that encapsulates the list, e.g.
public class MySomeService {
// This could be passed in, loaded from somewhere, etc.
private List<String> foo;
public void serviceMethod() {
doSomething();
String[] numbers = getNumericContaining();
doSomethingElse(numbers);
}
// The previous methods
private String[] getNumericContaining() {
foo.stream(). // and so on
}
It depends on whether your list really is a class in its own right, or whether it's just a special flavor that you need at some point. If it's the first, it may deserve its own class, if it's the latter, it doesn't.
Finally, even though OOP tells you to put data and behaviour in the same place, sometimes it makes sense to keep them in different places, so a method or a function can be used. Just pass the list as a parameter, and it'll work for all Collection classes not just your special one.
I have a switch case on some enum type depending on which I am creating an array.
It looks like:
switch (type) {
case BOOLEAN:
Boolean[] booleans = new Boolean[];
case STRING:
String[] strings = new String[];
}
I wonder is it possible to extract it to some method so it works like:
ArrayWrapper arrayWrapper = // some logic for which I am looking for
and then I have a generic method that accepts any type of array, and I would like to invoke it like
method(arrayWrapper.getArray()); and it will be casted to specific type and processed by specific type processor?
Java Generics combined with the Reflection API can be used in order to obtain an instance of T[]:
#SuppressWarnings("unchecked")
public static <T> T[] createArrayInstance(Class<T> clazz, int size) {
return (T[])Array.newInstance(clazz, size);
}
If you want to store, for any reason, a value in the resulting array:
#SuppressWarnings("unchecked")
public static <T> T[] createArrayInstance(T obj) {
T[] a = (T[])Array.newInstance(obj.getClass(), 1);//or whatever size you want
a[0] = obj;
return a;
}
See also: How to create a generic array in Java?
The java.lang.reflect.Array class provides functionality for working with any type of arrays, without knowing what type it is.
Using that class, you can write code like this:
public void example(Class<?> elemType) {
Object[] arr = (Object[]) Array.newInstance(elemType, 10);
// Do something with the array
}
(Don't cast to Object[] if you want to be able to work with arrays of primitive types.)
Array is part of the reflection system. That implies that you will have to used Class objects for element types, and probably have variables of Object type to refer to element values.
One possible way would be to bind the array's element type to a generic type parameter and tie the processor and the array together early on:
public class ArrayProcessingWrapper<T> {
private final T[] array;
private final ArrayProcessor<T> processor;
public ArrayProcessingWrapper(T[] array, ArrayProcessor<T> processor) {
super();
this.array = array;
this.processor = processor;
}
public void processArray() {
this.processor.process(this.array);
}
}
Another way might be along the lines of functions
public abstract class Processor<T> {
private final Supplier<T[]> arraySupplier;
public Processor(final Supplier<T[]> arraySupplier) {
super();
this.arraySupplier = arraySupplier;
}
public T[] createArray() {
return this.arraySupplier.get();
}
public void processNewArray() {
this.doProcess(this.createArray());
}
protected abstract void doProcess(T[] data);
}
public class BooleanProcessor extends Processor<Boolean> {
public BooleanProcessor(Supplier<Boolean[]> arraySupplier) {
super(arraySupplier);
}
#Override
protected void doProcess(Boolean[] data) {
// Do fancy boolean stuff...
}
}
But also have a look at Iterable<E> and/or Collection<E> (of which ArrayList<E> is what behaves the most like an array) instead of arrays.
To me, it seems like a design flaw if you need to use different logic ("processors") depending on the (runtime) type of an array.
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) {
...
}
}
I want to use ArrayList for example but besides only keeping an entry I want to store additional information: "write-in" time, some flag maybe. I could extend the class I am going to store but I want it to be the list feater. I thought maybe to do something like
public class PropertirizedArrayList<E> implements List<E> {
private static class TupleContainer<E>{
public E mainValue;
public Long hidingTime;
public Boolean flag;
}
private ArrayList<TupleContainer<E>> list = new ArrayList<>();
private ArrayList<TupleContainer<E>> delegate(){
return list;
}
//etc...
}
but I think it would be a great problem to reimplement all the List interface methods.
You can simply use List<TupleContainer<SomeType>>. I don't see a need to wrap the List with PropertirizedArrayList.
And if you do have some good reason to use a wrapper class (such a reason would be additional features that your wrapped list implements), you don't have to re-implement the existing List methods.
You have a List member contained within your class, so you can delegate each method of your class to the list.
For example :
public TupleContainer<E> get (int index)
{
return list.get (index);
}
Or if you don't want to expose TupleContainer :
public E get (int index)
{
return list.get (index).mainValue;
}
try this ...
private class TupleContainer<E>{
public E mainValue;
public Long hidingTime;
public Boolean flag;
}
List<TupleContainer<YourType>> list=new ArrayList<TupleContainer<YourType>>();
TupleContainer<YourType> tc=new TupleContainer<YourType>();
tc.mainValue=value;
tc.hidingTime=value;
tc.flag=value;
list.add(tc);
I have a generic method, for example:
public static<T> T execute(...) {
...
}
How can I define what type T is in the method body? For example:
if (T == String) {
// do something with strings
// return string;
}
if (T == Bitmap) {
// do something with bitmap
// return bitmap;
}
I tried the following, but it didn't work:
T par = null;
if(par instanceof String) {
// do something with strings
// return string;
}
I tried declaring par like below, but that didn't work either.
T par = (T) null;
T par = (T) new Object();
You could probably do something like this:
public static <T> T execute(Class<T> t) {
if(String.class == t) {
}
}
If your code only supports a discrete set of data types, you don't want to use generics. As mentioned in the comments on the original post, this situation calls for overloaded method calls.
Consider, for example, a situation where you support Strings, Integers, and Doubles, but you don't have specific logic for other data types. You would define your methods such as:
public static String execute(String s) { ... }
public static Integer execute(Integer i) { ... }
public static Double execute(Double d) { ... }
public static Object execute(Object o) { ... }
The first three methods would define the logic for the three discrete data types you do support, while the final would define logic and/or error handling for any other data types you do not support. (Of course, this doesn't cover primitives not of int or double type, but this is just an example.)
Generics were initially added to Java to support a Collection knowing exactly what it contained. It was a way of guaranteeing that a List held only Strings by declaring it a List<String>, for example. This capability was then extended, but the basic concept held -- guarantee that if you put an unknown object of type X in, even if you don't know what X is at compile time, you can write logic for getting that same type X out. (This article is an interesting read, if out-dated.)
This does not mean it should be used where the logic applied in a method or class is dependent on the data type of the input. It should be used where it doesn't matter the incoming data type, and the same logic will be applied consistently across the unknown data type X. So if you have different logic for String than Doubles, you should not be using generics.
tl;dr:
Since the original post indicated different logic based on the data type of the input parameter, therefore, generics are not appropriate to be used. Overloading the execute method based on the supported data types should be used instead.
T Here is known as Type Parameters.
// here will define the type of T in the method go()
public interface Comparable<T> {
public int compareTo(T t) {
// do something...
}
}
For eg:
I am having a class Song, and i want to sort the songs on the basis of its title.
public class Song implements Comparable<Song> {
private String title;
public void compareTo(Song s) {
title.compareTo(s.title());
}
public void setTitle(String s) {
this.title = s;
}
public void getTitle() {
return this.title;
}
public String toString() {
return getTitle();
}
}
If you're splitting the functionality in code that way already, and the inputs are the same, you'd probably be well served with different functions. So instead of(using Jeshurun's answer)
public static <T> T execute(Class<T> t)
{
if(String.class == t) {
}
}
BitMap b = execute(BitMap.class);
You would have
public BitMap bitmapExecute(...)
{
commonWork();
//do bitmap stuff
}
public String stringExecute(...)
{
commonWork();
//do String stuff
}
BitMap b = bitmapExecute(...);
String s = stringExecute(...);
If there's a large block of common code, with only a small section different based on type, you can move that common code to its own function.
public someObject commonWork(...)
{
//Do common stuff
}
As long as you are making the decision about the type at compile time, you shouldn't have to have instanceof blocks.