Java: Return array of functions - java

I have an array of methods which can be called and need a boolean as a parameter. I have tried this:
public class Example {
public Function<Boolean, Integer> getFunctions(boolean t) {
return new Function[] {
this::magicNumber
};
}
public int magicNumber(boolean t) {
return (t) ? new Random().nextInt(11) : 0;
}
}
But then the compiler returns an error message with the message
Incompatible types: invalid method reference
Incompatible types: Object cannot be converted to boolean
The example above however can work by storing the Function in a variable and returning that, however I don't find this clean code and it's redundant.
public class Example {
public Function<Boolean, Integer> getFunctions(boolean t) {
Function<Boolean, Integer> f = this::magicNumber;
return new Function[] {
f
};
}
public int magicNumber(boolean t) {
return (t) ? new Random().nextInt(11) : 0;
}
}
Is there any way to shorten the code above like in the example in the beginning?
EDIT
As a commenter requested, I will give a short example of how I used Supplier in a previous project. I return them in an array to return objects. The problem is that this project depends on having a parameter.
public Supplier<T>[] getRecipes()
{
return new Supplier[] {
this::anchovyRule,
this::codRule,
this::herringRule,
this::lobsterRule,
this::mackerelRule,
this::pikeRule,
this::salmonRule,
this::sardineRule,
this::shrimpRule,
this::troutRule,
this::tunaRule
};
}

How about return List<Function<Boolean, Integer>> like this.
public class Example {
public List<Function<Boolean, Integer>> getFunctions(boolean t) {
return Arrays.asList(
this::magicNumber
);
}
public int magicNumber(boolean t) {
return (t) ? new Random().nextInt(11) : 0;
}
}

Related

Predicate generic method

I wrote a Predicate code that takes any Object and tests it for the following conditions:
if Object type is String and contains "k" then it should return true.
if Object type is Integer and greater than 100 then it should return true.
if Object type is Employee which is class and having salary of employee greater than 60000, it should return true.
After writing that Predicate method I wrote the remove method that removes values from list according to Predicate method.
public class ConditionalRemove {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>(Arrays.asList("ramesh", "kushal", "suresh", "kc"));
System.out.println(conditionalRemove(list));
}
public static <T> List<T> conditionalRemove(ArrayList<T> list) {
ConditionCheck<T> cond = new ConditionCheck<>();
for (T t : list) {
if (cond.test(t)) {
list.remove(t);
}
}
return list;
}
static class ConditionCheck<T> implements Predicate<T> {
#Override
public boolean test(T t) {
if (t instanceof String) {
return (((String) t).contains("k"));
} else if (t instanceof Integer) {
return ((int) t > 100);
} else if (t instanceof Employee) {
return ((int) ((Employee) t).getSalary() < 60000);
}
return true;
}
}
}
After compiling this code I found Exception in thread "main" java.util.ConcurrentModificationException
The issue is you are updating the list when you are iterating over that. The issue can be fixed by updating code as
public static <T> List<T> conditionalRemove(ArrayList<T> list) {
ConditionCheck<T> cond = new ConditionCheck<>();
Iterator it = list.iterator();
while(it.hasNext())
{
it.next();
if (cond.test(t)) {
it.remove();
}
}
return list;
}
Since you're using Java 8, a functional approach would be to create a new filtered list:
public static <T> List<T> conditionalRemove(ArrayList<T> list) {
return list.stream()
.filter(new ConditionCheck<>())
.collect(Collectors.toList());
}
You can even replace the static inner class by just a method:
public static <T> List<T> conditionalRemove(ArrayList<T> list) {
return list.stream()
.filter(ConditionalRemove::test)
.collect(Collectors.toList());
}
private static <T> boolean test(T t) {
// your predicate implementation...
}
Don't reinvent the wheel: Use Collection#removeIf():
public static <T> List<T> conditionalRemove(ArrayList<T> list) {
list.removeIf(new ConditionCheck<>());
return list;
}
At one line, this is hardly worth the effort of creating a method to call... just make the single line call in-line:
public static void main(String[] args) {
List<String> list = new ArrayList<>(Arrays.asList("ramesh", "kushal", "suresh", "kc"));
list.removeIf(new ConditionCheck<>());
System.out.println(list);
}
Some data structures throws the java.util.ConcurrentModificationException when you modify them during an iteration, in order to do that with success you need use a synchronized structure such as "CopyOnWriteArrayList", this is the java doc reference
Hope this can help you!
Regards.

Java: not-void methods as map values

I have some code like this:
public class A {
private final Map<String, Runnable> map = new HashMap<>();
public A() {
map.put("a", () -> a());
map.put("b", () -> b());
}
public int a() {
return 1;
}
public int b() {
return 2;
}
public int c(String s) {
// map.get(s).run(); <= returns void, but
// I need the result of the
// function paired to the string.
// What TODO?
}
}
I have not-void functions (a(), b()) as values of a map, paired to Strings. I need to run the functions and get the result of the functions, and return it in the function c(). The run() function returns void, so I can't get the value from it. Is there any way to do this?
What you want to do here is to return an int value from the method. For that, you can't use a Runnable as run() doesn't return a value.
But you can use an IntSupplier, which is a functional interface representing a function supplying an int value. Its functional method getAsInt is used to return the value.
public class A {
private final Map<String, IntSupplier> map = new HashMap<>();
public A() {
map.put("a", () -> a()); // or use the method-reference this::a
map.put("b", () -> b()); // or use the method-reference this::b
}
public int a() {
return 1;
}
public int b() {
return 2;
}
public int c(String s) {
return map.get(s).getAsInt();
}
}
Additionally, if you don't want to return a primitive but an object MyObject, you can use the Supplier<MyObject> functional interface (or Callable<MyObject> if the method to call can throw a checked exception).
The fact that lambdas are new does not mean they are necessary for every (perhaps any) solution. Consider this tried-and-true java 5 feature (a little something called enumeration objects).
public class Enumery
{
private static enum Stuffs
{
a(1),
b(2);
Stuffs(final int value)
{
this.value = value;
}
public int kapow()
{
return value;
}
final int value;
}
public int thing(final String stuffsName)
{
final int returnValue;
final Stuffs theStuffs;
theStuffs = Stuffs.valueOf(stuffsName);
returnValue = theStuffs.kapow();
return returnValue;
}
}

Is there any way to stop a Stream.generate from its Lambda closure?

I just started playing around Java 8 and Lambda Expression and I am curious if I can stop the Stream generation from inside the Lambda expession by returning a specific value
(like null). Is this possible with Stream.generate()?
private int counter;
private void generate()
{
System.out.println(Stream.generate(() -> {
if (counter < 10) {
counter++;
return RandomUtils.nextInt(100);
} else {
return null;
}
}).count());
}
Unfortunately this code does not terminate, so by simply returning null will not step out of the stream.
Java 9 and later includes this method:
Stream<T> takeWhile(Predicate<? super T> predicate);
to limit a stream by condition. So the workaround beneath is not needed anymore.
Original answer (for Java versions earlier than 9):
With Stream.generate this is per definition not possible from a lambda closure. It is by definition endless. Using limit() you are able make your stream fix sized. But this will not help you for conditions like:
if random>10 then stop
There is a possibility to limit a potential endless stream by condition. This is usefull if one does not know the size. Your friend here is a Spliterator and your sample code would look like:
System.out.println( StreamSupport.stream(Spliterators.spliteratorUnknownSize(new Iterator<Integer>() {
int counter = 0;
#Override
public boolean hasNext() {
return counter < 10;
}
#Override
public Integer next() {
counter++;
return RandomUtils.nextInt(100);
}
}, Spliterator.IMMUTABLE), false).count());
Basically you are able to build a Stream from an Iterator. I am using this construct e.g. for a stream of XMLEvents from Stax XML - parsing.
I know this is not done by lambda constructs but it IHMO solves this lacking feature of stopping the stream item generation by condition.
I would be very interested, if there is a better way to achieve this (I mean this stream construct and not the XML processing ;)) or if there is a fundamental flaw in using streams in this way.
This is not possible with Lamdas, you cannot control the flow from inside the expression.
Even the API docs says that the Stream.generate generates an infinite stream.
However, you can limit the Stream and achieve the desired functionality simply by using the limit() method:
System.out.println(Stream.generate(() -> RandomUtils.nextInt(100)).limit(10).count());
// If you are not looking for parallelism, you can use following method:
public static <T> Stream<T> breakStream(Stream<T> stream, Predicate<T> terminate) {
final Iterator<T> original = stream.iterator();
Iterable<T> iter = () -> new Iterator<T>() {
T t;
boolean hasValue = false;
#Override
public boolean hasNext() {
if (!original.hasNext()) {
return false;
}
t = original.next();
hasValue = true;
if (terminate.test(t)) {
return false;
}
return true;
}
#Override
public T next() {
if (hasValue) {
hasValue = false;
return t;
}
return t;
}
};
return StreamSupport.stream(iter.spliterator(), false);
}
Use StreamSupport.stream(Spliterator, boolean)
See JavaDoc on Spliterator.
Here is example spliterator:
public class GeneratingSpliterator<T> implements Spliterator<T>
{
private Supplier<T> supplier;
private Predicate<T> predicate;
public GeneratingSpliterator(final Supplier<T> newSupplier, final Predicate<T> newPredicate)
{
supplier = newSupplier;
predicate = newPredicate;
}
#Override
public int characteristics()
{
return 0;
}
#Override
public long estimateSize()
{
return Long.MAX_VALUE;
}
#Override
public boolean tryAdvance(final Consumer<? super T> action)
{
T newObject = supplier.get();
boolean ret = predicate.test(newObject);
if(ret) action.accept(newObject);
return ret;
}
#Override
public Spliterator<T> trySplit()
{
return null;
}
}
This is another solution for java 8 (It needs a Stream.Builder, may be it is not optimal, but it is quite simple):
#SuppressWarnings("ResultOfMethodCallIgnored")
public static <T> Stream<T> streamBreakable(Stream<T> stream, Predicate<T> stopCondition) {
Stream.Builder<T> builder = Stream.builder();
stream.map(t -> {
boolean stop = stopCondition.test(t);
if (!stop) {
builder.add(t);
}
return stop;
})
.filter(result -> result)
.findFirst();
return builder.build();
}
And the test:
#Test
public void shouldStop() {
AtomicInteger count = new AtomicInteger(0);
Stream<Integer> stream = Stream.generate(() -> {
if (count.getAndIncrement() < 10) {
return (int) (Math.random() * 100);
} else {
return null;
}
});
List<Integer> list = streamBreakable(stream, Objects::isNull)
.collect(Collectors.toList());
System.out.println(list);
}
It is possible, you just need to think outside the box.
The following idea is borrowed from Python, the language which introduced me to generator functions...
Just throw an instance of RuntimeException when you are done from within the Supplier<T> closure and catch-and-ignore it at the call site.
An example excerpt (note I have added a safety catch of Stream.limit(Long.MAX_VALUE) to cover the unexpected, though it should never be triggered):
static <T> Stream<T> read(String path, FieldSetMapper<T> fieldSetMapper) throws IOException {
ClassPathResource resource = new ClassPathResource(path);
DefaultLineMapper<T> lineMapper = new DefaultLineMapper<>();
lineMapper.setFieldSetMapper(fieldSetMapper);
lineMapper.setLineTokenizer(getTokenizer(resource));
return Stream.generate(new Supplier<T>() {
FlatFileItemReader<T> itemReader = new FlatFileItemReader<>();
int line = 1;
{
itemReader.setResource(resource);
itemReader.setLineMapper(lineMapper);
itemReader.setRecordSeparatorPolicy(new DefaultRecordSeparatorPolicy());
itemReader.setLinesToSkip(1);
itemReader.open(new ExecutionContext());
}
#Override
public T get() {
T item = null;
++line;
try {
item = itemReader.read();
if (item == null) {
throw new StopIterationException();
}
} catch (StopIterationException ex) {
throw ex;
} catch (Exception ex) {
LOG.log(WARNING, ex,
() -> format("%s reading line %d of %s", ex.getClass().getSimpleName(), line, resource));
}
return item;
}
}).limit(Long.MAX_VALUE).filter(Objects::nonNull);
}
static class StopIterationException extends RuntimeException {}
public void init() {
if (repository.count() == 0) {
Level logLevel = INFO;
try {
read("providers.csv", fields -> new Provider(
fields.readString("code"),
fields.readString("name"),
LocalDate.parse(fields.readString("effectiveStart"), DateTimeFormatter.ISO_LOCAL_DATE),
LocalDate.parse(fields.readString("effectiveEnd"), DateTimeFormatter.ISO_LOCAL_DATE)
)).forEach(repository::save);
} catch (IOException e) {
logLevel = WARNING;
LOG.log(logLevel, "Initialization was interrupted");
} catch (StopIterationException ignored) {}
LOG.log(logLevel, "{} providers imported.", repository.count());
}
}
My solution was to generate a null when done and then apply a filter
Stream
.generate( o -> newObject() )
.filter( o -> o != null )
.forEach(...)

java generics T extends Simpletype?

I'd like to write a method, that does return something of a PrimitiveType like float, integer, boolean and also String if possible. I'd like to use generics for it but i stuck and dont find a solution for it. I do need it for a Configparser. Ill use it to get different values from the Config.
Current it des look like this and i know that the switch does not work like this but you get an idea of what id like to do:
public class ConfigurationManager extends XmlReader {
private final static String FILE_PATH = "config/config.cfg";
private static Element xml;
public ConfigurationManager() throws IOException {
FileHandle handle = Gdx.files.internal(FILE_PATH);
this.xml = this.parse(handle);
}
public Resolution getResolution() {
Resolution r = new Resolution();
r.height = xml.getFloat("height");
r.width = xml.getFloat("width");
return r;
}
public static <T> T getConfig(Class<T> type, String name) {
if (type.equals(Integer.class)) {
return type.cast(xml.getInt(name));
} else if (type.equals(Float.class)) {
return type.cast(xml.getFloat(name));
} else if (type.equals(Boolean.class)) {
return type.cast(xml.getBoolean(name));
} else if (type.equals(String.class)) {
return type.cast(xml.get(name));
}
throw new AssertionError("Invalid type");
}
}
Thanks alot
Well, I don't think you can do it with primitive types directly, but how about something like this:
public static <T> T getConfig(Class<T> type, String name) {
if(type.equals(Integer.class)){
return type.cast(xml.getInteger(name));
} else if(type.equals(Float.class)){
return type.cast(xml.getFloat(name));
} else if(type.equals(Double.class)) {
return type.cast(xml.getDouble(name));
} else if(type.equals(String.class)) {
return type.cast(xml.getString(name));
}
throw new AssertionError("Invalid type");
}
You could use an Enum to avoid the branching logic and the explicit casting.
public enum TypeSelector {
INTEGER() {
#Override
public Integer getValue(Elements xml, String name) {
return xml.getInteger(name);
}
},
DOUBLE() {
#Override
public Double getValue(Elements xml, String name) {
return xml.getDouble(name);
}
};
private static final Map<Class<?>, TypeSelector> SELECTORS = new HashMap<Class<?>, TypeSelector>() {
{
put(Integer.class, INTEGER);
put(Double.class, DOUBLE);
}
};
public static <T> TypeSelector getSelectorForType(Class<T> c) {
TypeSelector selector = SELECTORS.get(c);
if (selector == null) {
throw new AssertionError("Invalid type");
}
return selector;
}
public abstract <T> T getValue(Elements xml, String name);
}

Java: iterating through list of lists?

The question but in C#. So does Java have C#'s command? I need it for Matches-SearchTerm-Files-relationship.
foreach(var i in BunchOfItems.SelectMany(k => k.Items)) {}
[Why not for-loops?]
I have done such structures in nested for loops but they soon become bloated. So I prefer something more succint like the above.
public static Stack<Integer[]> getPrintPoss(String s,File f,Integer maxViewPerF)
{
Stack<File> possPrint = new Stack<File>();
Integer[] poss = new Integer[4]();
int u,size;
for(File f:files)
{
size = f2S(f).length();
u = Math.min(maxViewsPerF,size);
for(int i=0; i<u;i++)
{
// Do something --- bloated, and soon out of control
// wants more succintly
}
}
return possPrint;
}
for (List<Object> lo : list) {
for (Object o : lo) {
// etc etc
}
}
I don't think there's a simpler solution.
If you can get the data into an Iterable<Iterable<T>>, then you can get from that to a flattened Iterable<T> using Guava's Iterables.concat method. If what you have is really an Iterable<S>, with some way to get from an S to an Iterable<T>, well, then you have to first use Iterables.transform to view that as the Iterable<Iterable<T>> needed by concat.
All this will look a lot nicer if and when Java has something resembling closures, but at least today it's possible.
http://guava-libraries.googlecode.com
With Java 8, you can say
Collection bunchOfItems = ...;
bunchOfItems.stream().flatMap(k::getItems).forEach(i -> /* operate on i */);
or
Item[] bunchOfItems = ...;
Stream.of(bunchOfItems).flatMap(k::getItems).forEach(i -> /* operate on i */);
depending upon whether you have a Collection or an Array.
Have about half a year patience until JDK7 is final which will include Closures. This provides simliar syntax and the same possibilities as LINQ which was demonstrated in the answer you're talking about.
I have my own version. Waiting desperately for Closures in Java :
public static <T, E> Iterable<T> transformMany(Iterable<E> iterable, Func<E, Iterable<T>> f) {
if (null == iterable)
throw new IllegalArgumentException("null iterable");
if (null == f)
throw new IllegalArgumentException("null f");
return new TransformManyIterable<E, T>(iterable, f);
}
public interface Func<E, T> {
T execute(E e);
}
public class TransformManyIterable<TOriginal, TResult> implements Iterable<TResult> {
private Iterable<TOriginal> iterable;
private Func<TOriginal, Iterable<TResult>> func;
public TransformManyIterable(Iterable<TOriginal> iterable,
Func<TOriginal, Iterable<TResult>> func) {
super();
this.iterable = iterable;
this.func = func;
}
class TransformIterator implements Iterator<TResult> {
private Iterator<TOriginal> iterator;
private Iterator<TResult> currentIterator;
public TransformIterator() {
iterator = iterable.iterator();
}
#Override
public boolean hasNext() {
if (currentIterator != null && currentIterator.hasNext())
return true;
else {
while (iterator.hasNext()) {
Iterable<TResult> iterable = func.execute(iterator.next());
if (iterable == null)
continue;
currentIterator = iterable.iterator();
if (currentIterator.hasNext())
return true;
}
}
return false;
}
#Override
public TResult next() {
if (currentIterator != null && currentIterator.hasNext())
return currentIterator.next();
else {
while (iterator.hasNext()) {
Iterable<TResult> iterable = func.execute(iterator.next());
if (iterable == null)
continue;
currentIterator = iterable.iterator();
if (currentIterator.hasNext())
return currentIterator.next();
}
}
throw new NoSuchElementException();
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
#Override
public Iterator<TResult> iterator() {
return new TransformIterator();
}
}
Usage:
Iterable<SomeType> result = transformMany(input, new Func<InputType, Iterable<SomeType>>() {
#Override
public Iterable<SomeType> execute(InputType e) {
return new ArrayList<SomeType>();
}
});
The SelectMany method is part of LINQ which is .Net-specific. This question asks about a LINQ equilvalent for java. Unfortunately, it doesn't look like there is a direct equivalent.

Categories

Resources