Passing the method to method - java

I have a method which uses Deque. In 1 place, sometimes I want to Deque.pullFirst() and sometimes Deque.pullLast(). It should depend on one of the arguments passed to the method. How do this with Java 8?
This is my try with Callable I know that it doesn't work but now you can understand what I want to achieve:
public class AppMain {
public void iterateThroughQueue(Callable callable) { // error
Deque<Integer> deq = new ArrayDeque<>();
deq.add(1);
deq.add(2);
deq.add(3);
for (int i = 0; i < 3; i++) {
System.out.println(callable.apply(deq)); // error!
}
System.out.println("size after iteration = " + deq.size());
}
public static void main(String[] args) {
AppMain.iterateThroughQueue(Deque::pollFirst); // error!
}
}

Method references are either:
Consumer<T>, which means they take a parameter and return nothing. For example System.out::println is a Consumer<String>.
Producer<T>, which means they take no parameter and return something. For example UUID::randomUUID is a Producer<UUID>.
Function<T,Z>, which means they take a parameter of type T (can be the instance on which to apply the method) and return a result of type Z, in your case Deque::pollFirst take is a Function<Deque<Integer>, Integer>. Another example is deq::add where deq is an instance of Deque<Integer> which would be a Function<Integer, Boolean> .
So you should be using Function<Deque<Integer>, Integer> instead of Callable which is for something completely different. Also iterateThroughQueue(...) need to be static.

Callable will not work here, but Function will.
You could try instead this:
public static void iterateThroughQueue(Function<Deque<Integer>, Integer> function) {
Deque<Integer> deq = new ArrayDeque<>();
deq.add(1);
deq.add(2);
deq.add(3);
for (int i = 0; i < 3; i++) {
System.out.println(function.apply(deq));
}
System.out.println("size after iteration = " + deq.size());
}
public static void main(String[] args) {
iterateThroughQueue(Deque::pollFirst);
}
This prints:
1
2
3
size after iteration = 0

Related

Generic Supplier for n Getters Across Collection

I have a collection of Java objects where I want to run a single function across multiple values I might find in some of the object's member variables. I'm looking for a nice way to pass in which getter should be used so I can have one method do all that work. I was thinking about something like a Supplier, but that would mean I have to have one per instance of the class. Here's an example of what I'm trying to do (only I would like to do this without the if statement or with potentially n getters a switch statement:
import java.util.ArrayList;
import java.util.List;
public class TestSupplier {
private int varA;
private int varB;
public TestSupplier(int varA, int varB) {
this.varA = varA;
this.varB = varB;
}
public int getA() {
return this.varA;
}
public int getB() {
return this.varB;
}
public static void main(String[] args) {
List<TestSupplier> testList = new ArrayList<>();
testList.add(new TestSupplier(1, 11));
testList.add(new TestSupplier(2, 22));
// Can I pass something like a generic supplier instead of a bool?
TestSupplier.someCollectorFunction(testList, true);
TestSupplier.someCollectorFunction(testList, false);
}
public static void someCollectorFunction(List<TestSupplier> list, boolean isA /* what if I want more than one getter*/) {
int sum = 0;
for (TestSupplier obj: list) {
// This is where I wish I could have a generic supplier or something
if (isA) {
sum = sum + obj.getA();
}
else {
sum = sum + obj.getB();
}
}
System.out.println("I have a sum: " + sum);
}
}
Is there something is Java's functional API that would let me do this?
It sounds like what you want is
ToIntFunction<TestSupplier> fn = isA ? TestSupplier::getA : TestSupplier::getB;
for (TestSupplier obj: list) {
sum += fn.applyAsInt(obj);
}
It's up to you whether you consider that an improvement.
You could also pass in the ToIntFunction instead of the boolean, passing in TestSupplier::getA instead of true etc.

How to create a class with a list of elements from another class without breaking the dependency injection rule?

I have class that has several fields.
public class Foo {
int firstCoef;
int secondCoef;
public Foo(String args){
this.firstCoef=Integer.parseInt(args[0]);
this.secondCoef=Integer.parseInt(args[1]);
}
}
The arguments are assigned this way because I create several members of this class by reading data from .csv.
I have another class that manages a list of Foo instances. It creates the whole list at once by reading it from file and uses the list for calculation. When creating a list in class constructor, it uses new Foo(string).
public class FooManager {
protected List<Foo> allFoos = new ArrayList<Foo>();
public FooManager(List<String[]> input) {
String[] line;
for (int lineNumber = 0; lineNumber < input.size(); lineNumber++) {
line = input.get(lineNumber);
allFoos.add(new Foo(line));
}
}
public int calculate(int number) {
int result = 0;
for (Foo foo : allFoos) {
result += Math.pow(number + foo.getFirstCoef(), foo.getSecondCoef());
}
return result;
}
}
From what I understand, this is considered bad design because the dependencies can't be injected. Also, it is hard to test. How could I change the design without complicating the input? The only goal of both classes is to be able to perform the calculation in the end.
You could add another layer, by adding a class that does the translation from the List to List:
public class FooParser implements Function<String[], Foo> {
public Foo apply(String[] input)
for (int lineNumber = 0; lineNumber < input.size(); lineNumber++) {
String[] line = input.get(lineNumber);
allFoos.add(new Foo(line));
}
}
}
And then use it in the constructor of FooManger:
public FooManager(FooParser parser, List<String[]> input) {
allFoos = parser.apply(input);
}
This way you have another part of logic in separate class - and it is easier to test in isolation.

Java multithreading, accessing list from separate classes

Just to start off, I'm pretty inept at Java and especially multithreading, so what I'm asking might sound a bit ordinary. I am attempting to create a program in which I create three threads which each accomplish the specific task of depicting certain values between ten integers, such as average, deviation, etc. How would I approach this?
I am attempting to create four classes, one for the main program, and three for each of the calculations of the values between each: class "Average" for the average of the ten numbers in the array, class "Median" for the median, etc. The code for the other 3 classes I can easily write, no problem there. My main problem is that since the list "integers" is not available outside the class, I can't write the code for finding each of the values I need in the three programs.
Is there a better way to write this so I can actually access the list from inside the classes for each of the threads?
import java.util.*;
public class ThreadDemo
{
public static void main(String[] args)
{
Random number = new Random();
List integers = new ArrayList();
for (int i = 0; i < 10; i++)
{
integers.add(number.nextInt(101));
}
Thread average = new Thread(new Average());
Thread median = new Thread(new Median());
Thread deviation = new Thread(new Deviation());
average.start();
median.start();
deviation.start();
}
}
class Average extends Thread
{
public void run()
{
// code for finding average
}
}
class Median extends Thread
{
public void run()
{
// code for finding median
}
}
class Deviation extends Thread
{
public void run()
{
// code for finding deviation
}
}
There are a lot of options to achieve what you are trying to do. I will outline two:
each computation method implementing the Callable interface and taking data into the instance constructor;
each computation method implementing the Function interface and passing data into the call via the closure.
It is generally advisable to program to interfaces, that is require an interface as method argument. All below examples follow this by implementing Callable or Function and working with those high level interfaces elsewhere. The code for both cases looks very similar with the main difference being the remapping of Function to Callable in the latter case using the closure state.
Let's start with some common utilities (statics for brevity only):
The following method will create a Collection of 100 random integers in [0,100]:
private static Collection<Integer> ints() {
Random random = new Random();
return random.ints(100, 0, 100)
.boxed()
.collect(Collectors.toList());
}
The following method will execute a collection of Callables concurrently on a cached executor pool. Each callable is generic and will deliver a double value. Those values (in random order) will be collected and returned as a list:
private static List<Double> concurrently(Collection<Callable<Double>> callables) throws InterruptedException, ExecutionException {
ExecutorService executors = Executors.newCachedThreadPool();
Collection<Future<Double>> futures = executors.invokeAll(callables);
List<Double> res = new ArrayList<>();
for (Future<Double> future: futures) {
res.add(future.get());
}
executors.shutdownNow();
return res;
}
Now let's get back to the core logic.
Case 1: Implementing Callable
class Averager<V extends Number> implements Callable<Double> {
private final Collection<V> values = new ArrayList<>();
Averager(Collection<V> values) {
this.values.addAll(values);
}
#Override
public Double call() {
double sum = 0.0;
for (V value : values) {
sum += value.doubleValue();
}
return Double.valueOf(sum / values.size());
}
}
class Medianer<V extends Number> implements Callable<Double> {
private final Collection<V> values = new ArrayList<>();
Medianer(Collection<V> values) {
this.values.addAll(values);
}
#Override
public Double call() {
List<V> sorted = new ArrayList<>(values);
sorted.sort(Comparator.comparingDouble(Number::doubleValue));
// TODO treat odd/even number of elements separately
return Double.valueOf(sorted.get(sorted.size() / 2).doubleValue());
}
}
Note: whenever you take a collection as a constructor argument, do not store the reference to the original collection provided in a private field, copy values. If collections are very large, do not pass them to constructor or make unmodifiable.
#Test
public void usingCallable() throws InterruptedException, ExecutionException {
Collection<Integer> values = ints();
Collection<Callable<Double>> callables = new ArrayList<>();
callables.add(new Averager<>(values));
callables.add(new Medianer<>(values));
List<Double> res = concurrently(callables);
System.out.println(res);
}
Case 2: Implementing Function
class Averager<V extends Number> implements Function<Collection<V>, Double> {
#Override
public Double apply(Collection<V> values) {
double sum = 0.0;
for (V value : values) {
sum += value.doubleValue();
}
return Double.valueOf(sum / values.size());
}
}
class Medianer<V extends Number> implements Function<Collection<V>, Double> {
#Override
public Double apply(Collection<V> values) {
List<V> sorted = new ArrayList<>(values);
sorted.sort(Comparator.comparingDouble(Number::doubleValue));
// TODO treat odd/even number of elements separately
return Double.valueOf(sorted.get(sorted.size() / 2).doubleValue());
}
}
#Test
public void usingFunction() throws InterruptedException, ExecutionException {
Collection<Integer> values = ints();
Collection<Function<Collection<Integer>, Double>> functions = new ArrayList<>();
functions.add(new Averager<>());
functions.add(new Medianer<>());
List<Callable<Double>> callables = functions.stream().map(f -> (Callable<Double>) () -> f.apply(values)).collect(Collectors.toList());
List<Double> res = concurrently(callables);
System.out.println(res);
}
I personally prefer the latter one because your computation methods become generic functions, that is implementing the generic Function interface and can be used in other contexts.
Reworking case 1 and 2 with lambdas
You can do some interesting things with lambdas here. For the case of functions, you can just predefine them as lambdas instead of constructing new instances of specifically defined class:
static final Function<Collection<Integer>, Double> averager = (values) -> {
double sum = 0.0;
for (Integer value : values) {
sum += value.doubleValue();
}
return Double.valueOf(sum / values.size());
};
static final Function<Collection<Integer>, Double> medianer = (values) -> {
List<Integer> sorted = new ArrayList<>(values);
sorted.sort(Comparator.comparingDouble(Number::doubleValue));
// TODO treat odd/even number of elements separately
return Double.valueOf(sorted.get(sorted.size() / 2).doubleValue());
};
Followed later by:
Collection<Function<Collection<Integer>, Double>> functions = new ArrayList<>();
functions.add(averager);
functions.add(medianer);
For the case of callable you can nicely inline them:
Collection<Callable<Double>> callables = new ArrayList<>();
callables.add(() -> {
double sum = 0.0;
for (Integer value : values) {
sum += value.doubleValue();
}
return Double.valueOf(sum / values.size());
});
callables.add(() -> {
List<Integer> sorted = new ArrayList<>(values);
sorted.sort(Comparator.comparingDouble(Number::doubleValue));
// TODO treat odd/even number of elements separately
return Double.valueOf(sorted.get(sorted.size() / 2).doubleValue());
});
Note how you do not need external declarations in the latter case.
Note: as you do not want your results in a random order you will need you function return a pair, e.g. Map.Entry, with a key and a value. But I will leave that to you to exercise.
A sample execution for one of those methods would print something like
[53.01,57.0]
You can pass as a constructor argument. Also, after starting the threads, you must call join, otherwise the main thread will not wait the others to finish:
average.start();
median.start();
deviation.start();
average.join();
median.join();
deviation.join();
```

java generics compile error, generic class on the stack

I'm not sure why this doesn't work in Java:
import java.util.Map;
public class FreqCounter<T,R> {
private Map<T, Integer> hist;
private R item;
public FreqCounter (final R item_) {
item = item_;
}
public T getMostFrequentElement() {
T most_frequent_element = T();
Integer highestcount = 0;
for(T t : item) {
Integer count = hist.get(t);
if(count == null) {
hist.put(t, 1);
}
else {
hist.put(t, count + 1);
}
if(count + 1 > highestcount) {
most_frequent_element = t;
highestcount = count + 1;
}
}
return most_frequent_element;
}
}
class HelloWorld {
public static void main(String[] args) {
String s = "aaabbcccc";
FreqCounter<Character, Integer> counter = new FreqCounter<Character, Integer>(s);
}
}
Problem lines:
1. T most_frequent_element = T();
2. for(T t : item)
3. FreqCounter<Character, Integer> counter = new FreqCounter<Character, Integer>(s);
Cannot find symbol: method T()
required: array or java.lang.Iterable, found: R
Required java.lang.Integer
Found: java.lang.String
reason: actual argument java.lang.String cannot be converted to java.lang.Integer by method invocation conversion
What I was trying to do was make a class that could count how many times an element in an iterable container shows up. Originally I just wanted to make it to count characters in a string but I thought I could make it more general. I think some of this would work in C++?
Also, does FreqCounter<Character, Integer> counter = new FreqCounter<Character, Integer>(s); need to be "newed" as opposed to declared on the stack?
T is a Generic type, not a real one, and one of the limitations of generics is that you cannot instantiate a new one (which is what I think you were trying to do here).
What you can do though is assign, call methods in, keep references too, duplicate references too, etc.
What you probably actually wanted to do was pull the set of Ts out of the keySet of the Map.
T t = null;
int count = 0;
for (Entry<T, Integer> e: hist.entrySet()) {
if (e.getValue() > count) {
count = e.getValue();
t = e.getKey();
}
}
return t;
Java Generics provide a lot of the same functionality that C++ templates do, but they work in quite a different way. Quite apart from anything else you only have one ArrayList class no matter how many different ways you instantiate one. The generics are used for compiler time type checking and then erased and are not present at all during run time.

Invoking a same method just once in java

I have four different classes classA, classB, classC and classD. All the four classes have the same static method search() which takes two string parameters. If i want to invoke static method search in four different classes from main class at once. How can I do that. For now my code is as follows for main class. I need to execute the same thing for other 3 classes also. How can i do that and display the results of other 3 in the same way as for classA. The way search is done in 4 classes r different but they should give the same result.
Main() {
Object[] zy;
for (String pattern : Read.arrayList) {
List<Integer> results = ClassA.findAll(pattern, dataToSearch);
zy = results.toArray();
for (int i = 0; i < zy.length; i++) {
System.out.println(" Pattern searched " + pattern + " match is found at index : "+ results);
}
}
if (zy.length == 0) {
System.out.println("Nothing matched");
}
}
I strongly recommend you change this to non-static methods. Look how easy and nice is when you will seperate an interface:
public interface Common {
List<Integer> findAll(String pattern, String dataToSearch);
}
public class A implements Common ...
public class B implements Common ...
public class C implements Common ...
public class D implements Common ...
// in main:
List<Common> allYourClasses = new ArrayList<Common>();
allYourClasses.add(new A());
allYourClasses.add(new B());
allYourClasses.add(new C());
allYourClasses.add(new D());
List<Integer> result = new ArrayList<Integer>();
for (Common c : allYourClasses) {
result.addAll(c.findAll(pattern, dataToSearch));
}
1 - You should NOT do this. Avoid static methods. One of the reason being they can not be called without the exact class. A group of classes that implement a simple interfaces will work faster, safer and better in every way
2 - You can (but you shouldn't) do something like this:
for (Class<?> clazz : new Class[] { ClassA.class, ClassB.class,
ClassC.class }) {
Object[] zy = null;
String dataToSearch = "";
String[] arrayList = { "a" };
for (String pattern : arrayList) {
List<Integer> results = findAllForClass(clazz, pattern,
dataToSearch);
zy = results.toArray();
for (int i = 0; i < zy.length; i++) {
System.out.println(" Pattern searched " + pattern
+ " match is found at index : " + results);
}
}
if (zy.length == 0) {
System.out.println("Nothing matched");
}
}
#SuppressWarnings("unchecked")
public static List<Integer> findAllForClass(Class<?> clazz, String pattern,
String dataToSearch) {
List<Integer> list = null;
try {
list = (List<Integer>) clazz.getDeclaredMethod("findAll", String.class,
String.class).invoke(null, pattern, dataToSearch);
} catch (Exception e) {
list = Collections.emptyList();
}
return list;
}
You see the #supresswarning and the try/catch? well, this is a hint: is telling you you this code is at least suspicious. It is in fact unsafe, non well performant, and is a stupid workaround.
(But we all did something like that once in our lives)
I can't really figure out why would anyone do that.
That said, you could have a method taking a Class as a parameter and calling the method explicitly by name (getMethod.../invoke()).
That puts you back in non static world and you can iterate over the classes you want to invoke. (But again, why use statics in the first place?)
Pseudo untested code:
public void invokeStatic(Class clazz, String method, Class<?> paramsTypes[], Object[] params) {
Method method = clazz.getMethod(method, paramsType);
method.invoke(params);
}
If you want to group all of the results together, just keep adding results to your list:
List<Integer> results = ClassA.findAll(pattern, dataToSearch);
results.addAll(ClassB.findAll(pattern, dataToSearch));
// etc.

Categories