Given this method:
public void walk( String path , ArrayList<String> files, String ext)
which collects all files into the ArrayList<> files starting at path and with given extension ext, I'm looking for a way to stop the search when a certain condition is met. For example, it should stop when files.size() becomes greater than a given number. How could I do this without modifying the method walk() ?
By not modifying the method, I mean not touching the source code in the editor. It's in a state that I like, and I don't want to touch it, because it's just for testing purpose.
Create your class extending ArrayList and override add method:
public class MyList extends ArrayList<String> {
#Override
public boolean add(String item) {
boolean added = super.add(item);
if (added && size() >= 10) {
throw MaxItemsReachedException();
}
}
}
When size is greater or equals to 10, for instance, you can throw an exception.
And call your method with an instance of MyList instead of ArrayList:
MyList list = new MyList();
walk("path", list, "extension");
DISCLAIMER: This is bad programming practice. Dont't do this. I only offer it because it solves the OP's problem.
Subclass ArrayList. Add some logic to the add methods that throw an exception if files.size is greater than some threshold.
It will look like this
public void add(E element){
if(size()<THRESHOLD){
super.add(element);
}else{
throw new RuntimeException("STOP HERE");
}
}
Try to throw an exception that walk does not catch and you should catch this exception in the method that calls walk.
Among other bad things this is using exceptions to manage flow control.
Related
Is method chaining good?
I am not against functional programming that uses method chaining a lot, but against a herd mentality where people mindlessly run behind something that is new.
The example, if I am processing a list of items using stream programming and need to find out the exact row that resulted into throwing NullPointerException.
private void test() {
List<User> aList = new ArrayList<>();
// fill aList with some data
aList.stream().forEach(x -> doSomethingMeaningFul(x.getAddress()));
}
private void doSomethingMeaningFul(Address x) {
// Do something
}
So in the example above if any object in list is null, it will lead to NullPointerException while calling x.getAddress() and come out, without giving us a hook to identify a User record which has this problem.
I may be missing something that offers this feature in stream programming, any help is appreciated.
Edit 1:
NPE is just an example, but there are several other RuntimeExceptions that could occur. Writing filter would essentially mean checking for every RTE condition based on the operation I am performing. And checking for every operation will become a pain.
To give a better idea about what I mean following is the snippet using older methods; I couldn't find any equivalent with streams / functional programming methods.
List<User> aList = new ArrayList<>();
// Fill list with some data
int counter = 0;
User u = null;
try {
for (;counter < aList.size(); counter++) {
u = aList.get(counter);
u.doSomething();
int result = u.getX() / u.getY();
}
} catch(Exception e) {
System.out.println("Error processing at index:" + counter + " with User record:" + u);
System.out.println("Exception:" + e);
}
This will be a boon during the maintenance phase(longest phase) pointing exact data related issues which are difficult to reproduce.
**Benefits:**
- Find exact index causing issue, pointing to data
- Any RTE is recorded and analyzed against the user record
- Smaller stacktrace to look at
Is method chaining good?
As so often, the simple answer is: it depends.
When you
know what you are doing
are be very sure that elements will never be null, thus the chance for an NPE in such a construct is (close to) 0
and the chaining of calls leads to improved readability
then sure, chain calls.
If any of the above criteria isn't clearly fulfilled, then consider not doing that.
In any case, it might be helpful to distribute your method calls on new lines. Tools like IntelliJ actually give you advanced type information for each line, when you do that (well, not always, see my own question ;)
From a different perspective: to the compiler, it doesn't matter much if you chain call. That really only matters to humans. Either for readability, or during debugging.
There are a few aspects to this.
1) Nulls
It's best to avoid the problem of checking for nulls, by never assigning null. This applies whether you're doing functional programming or not. Unfortunately a lot of library code does expose the possibility of a null return value, but try to limit exposure to this by handling it in one place.
Regardless of whether you're doing FP or not, you'll find you get a lot less frustrated if you never have to write null checks when calling your own methods, because your own methods can never return null.
An alternative to variables that might be null, is to use Java 8's Optional class.
Instead of:
public String myMethod(int i) {
if(i>0) {
return "Hello";
} else {
return null;
}
}
Do:
public Optional<String> myMethod(int i) {
if(i>0) {
return Optional.of("Hello");
} else {
return Optional.empty();
}
Look at Optional Javadoc to see how this forces the caller to think about the possibility of an Optional.empty() response.
As a bridge between the worlds of "null represents absent" and "Optional.empty() represents absent", you can use Optional.ofNullable(val) which returns Empty when val == null. But do bear in mind that Optional.empty() and Optional.of(null) are different values.
2) Exceptions
It's true that throwing an exception in a stream handler doesn't work very well. Exceptions aren't a very FP-friendly mechanism. The FP-friendly alternative is Either -- which isn't a standard part of Java but is easy to write yourself or find in third party libraries: Is there an equivalent of Scala's Either in Java 8?
public Either<Exception, Result> meaningfulMethod(Value val) {
try {
return Either.right(methodThatMightThrow(val));
} catch (Exception e) {
return Either.left(e);
}
}
... then:
List<Either<Exception, Result>> results = listOfValues.stream().map(meaningfulMethod).collect(Collectors.toList());
3) Indexes
You want to know the index of the stream element, when you're using a stream made from a List? See Is there a concise way to iterate over a stream with indices in Java 8?
In your test() function you are creating an emptylist List<User> aList = new ArrayList<>();
And doing for each on it. First add some element to
aList
If you want to handle null values you can add .filter(x-> x != null) this before foreach it will filter out all null value
Below is code
private void test() {
List<User> aList = new ArrayList<>();
aList.stream().filter(x-> x != null).forEach(x -> doSomethingMeaningFul(x.getAddress()));
}
private void doSomethingMeaningFul(Address x) {
// Do something
}
You can write a black of code in streams. And you can find out the list item which might result in NullPointerException. I hope this code might help
private void test() {
List<User> aList = new ArrayList<>();
aList.stream().forEach(x -> {
if(x.getAddress() != null)
return doSomethingMeaningFul(x.getAddress())
else
system.out.println(x+ "doesn't have address");
});
}
private void doSomethingMeaningFul(Address x) {
// Do something
}
If you want you can throw NullPointerException or custom excption like AddressNotFoundException in the else part
We have a huge project where many methods have been declared upfront and implementations are in progress. All declared methods have a body which simply throws an exception, say, UnimplException.
Now since the methods have been declared and a valid (compilable) body has been provided, they can be called from within other methods.
Now the question is that is there any way to list all such unimplemented (having just a compilable body throwing a particular exception) methods given a particular method?
To illustrate more(the code is to convey the idea and not strictly compiler friendly):
class A {
methA () {
throw new UnimplException();
}
}
class B {
methB () {
// proper body
// and calls methA
A.methA();
// does something else
// and returns.
}
}
class C {
methC () {
// proper body
// calls methB
B.methB();
}
}
So, if we start from, say, methC, then we want to travel all the way down the method tree to reach to methA because methC calls methB (which is properly implemented and we are not interested) which in turn calls methA which is not properly implemented and that is what we want to find.
We want to search for all such unimplemented methods starting from a method and going few levels deep until we cover all such unimplemented methods.
We thought of JavaAssist but we aren't sure how to go down all the levels because it seems to be giving us all methods called from within a method but not recursively.
Any help is greatly appreciated :)
Have you seen this project: https://github.com/gousiosg/java-callgraph? This appears to do the Java introspection part, listing every method call from every method in a jar file. I'd try using that to do the heavy lifting of parsing your code, then just recurse through the results.
Something like:
Use the callgraph code to build a list of all method calls.
Save that data somewhere.
Recursively parse that structure to find matching methods.
So from your example, step 1 would give something like the following:
A:methA -> UnimplException:<init>
B:methB -> A:methA
C:methC -> B:methB
Then shove those in a Multimap and do a fairly straightforward recursive search:
// this is populated from the output of the callgraph code
com.google.common.collect.Multimap<String, String> methodMap;
void checkAllMethods() {
for (String method : methodMap.keySet()) {
List<String> callStack = new ArrayList<>();
if (doesMethodThrowUnimplException(method, callStack)) {
System.out.println(method);
// can print callStack too if interested
}
}
}
boolean doesMethodThrowUnimplException(String method, List<String> callStack) {
for (String child : methodMap.get(method)) {
// have to check the exact method name from callgraph
if (child.equals("UnimplException:<init>")) {
return true;
}
// recurse into child if not already seen
if (!callStack.contains(child)) {
callStack.add(child);
if (doesMethodThrowUnimplException(child, callStack)) {
return true;
}
callStack.remove(callStack.size() - 1);
}
}
return false;
}
Doesn't strictly satisfy your requirements as this will report any method which throws the UnimplException, not those who only throw the exception, but not sure if that matters.
Standard disclaimer - just typed this in - haven't compiled / run it, so may well be typos, but hopefully the idea helps.
Currently, I'm getting stuck with what it seems to be an unexpected error.
I'm programming with the java language, using eclipse as IDE.
The List in question is declared as follows :
private final List<Integer> resList;
Using the "Watchpoint" feature of eclipse while debugging the program, I've seen the following process :
After returning the resList List two times, and before returning it for the third time, the List became suddenly empty.
If anyone have a suggestion to give me in order to fix that problem, I would be very pleased ?
Concerning the code, I posted all the methods that access the resList list and are invoked in the program :
Here is the first One :
public CloudInformationService(String name) throws Exception {
super(name);
resList = new LinkedList<Integer>();
arList = new LinkedList<Integer>();
gisList = new LinkedList<Integer>();
}
And the second one :
public void processEvent(SimEvent ev) {
int id = -1; // requester id
switch (ev.getTag()) {
...
// A resource is requesting to register.
case CloudSimTags.REGISTER_RESOURCE:
resList.add((Integer) ev.getData());
break;
...
}
}
And finally, The third one :
private static CloudInformationService cis;
public static List<Integer> getCloudResourceList() {
if (cis == null) {
return null;
}
return cis.getList();// The implementation of this method is listed below
}
public List<Integer> getList() {
return resList;
}
Thank you in advance.
Step 1: use ctrl+alt+H to look up references to resList and look for methods calling remove, clear, removeAll. If there are too many methods using resList move on to Step 2.
Step 2: Set breakpoints in the CloudInformationServices constructor, when hit, set up breakpoints in LinkedList/AbstractList (in the JDK) in all remove, clear, removeAll methods. In the breakpoints view, right click on resList and choose instance breakpoints. Pick all your remove, clear, removeAll breakpoints and continue execution. Now you'll get a breakpoint hit and can observe from where the list is being emptied.
Without any more code there isn't much help you can get I'm afraid.
I can write a nested loop to iterate over the elements of a nested array, the for-each elegantly hides the details of the traversal over each level of the nested array:
Foo[][] dbl_array;
public void do_all() {
// Iterate over both levels of a nested array, invoking "bar" on each inner element.
for (final Foo[] arr_1d : dbl_array) {
for (final Foo el : arr_1d) {
el.bar();
}
}
}
But the problems with this approach are:
The fact that a doubly-nested loop is needed to traverse the data structure is painfully obvious here.
I have to copy this nested loop for every function I need to call on the inner elements.
This breaks the encapsulation of the method for traversing the structure. I may choose to implement the nested array with some other structure and don't want to change every copy of the nested iterations to whatever traversal method is needed.
The structure of the nested for-each loops is inside out from what is needed. Instead of having the desired function call inside the nests, an Iterator should handle the data structure traversal internally, exposing each entry encountered during the traversal.
So...how do I change this so that I implement an Iterator that I could invoke like:
Foo_Iterator fi = Foo.iterator();
for (final Foo el : fi) { // The Iterator hides the traversal details from the caller.
el.bar(); // The desired function is invoked on each element encountered.
}
This would leave the details of how the iteration is done to the Foo_Iterator class.
My question is "How do I write Foo_Iterator, keeping track of the state of the nested iterators?
I think it would look something like the following, but I'm missing the bits that keep track of the state.
class Foo_Iterator extends Whiz implements Iterator {
public Foo_Iterator() {
// Initialize state based on access to the superclass Whiz.
}
public boolean hasNext() {
// Is there an elegant way to save the state of both iterators between each call to hasNext() and next()?
// The "inelegant" way would be to keep track of the inner and out array indices,
// comparing the current index to the array length...
}
public Foo next() {
// Access the "next" in the nested sequence.
}
public void remove() {
// I probably won't implement or need/use this one.
}
}
Any suggestions on how to do this the "elegant" way?
Thanks.
Not sure if this is any more elegant, but you can use iterators too keep track of the state for you (using String for example purposes):
class FooIterator implements Iterator<String> {
private final Iterator<String[]> outer;
private Iterator<String> inner = null;
public FooIterator(String[][] data) {
outer = Arrays.asList(data).iterator();
nextInner();
}
private void nextInner() {
if (outer.hasNext())
inner = Arrays.asList(outer.next()).iterator();
}
public boolean hasNext() {
return inner != null && inner.hasNext();
}
public String next() {
String next = inner.next();
if (!inner.hasNext())
nextInner();
return next;
}
public void remove() {
// not used
}
}
I actually don't think there's anything wrong with keeping track of the two indices.
Of course, in your code fi should really be an Iterable (presumably your super class), which instantiates FooIterator, which the consumers should never see.
i'm looking for an implementation of SortedSet with a limited number of elements. So if there are more elements added then the specified Maximum the comparator decides if to add the item and remove the last one from the Set.
SortedSet<Integer> t1 = new LimitedSet<Integer>(3);
t1.add(5);
t1.add(3);
t1.add(1);
// [1,3,5]
t1.add(2);
// [1,2,3]
t1.add(9);
// [1,2,3]
t1.add(0);
// [0,1,2]
Is there an elegant way in the standard API to accomplish this?
I've wrote a JUnit Test for checking implementations:
#Test
public void testLimitedSortedSet() {
final LimitedSortedSet<Integer> t1 = new LimitedSortedSet<Integer>(3);
t1.add(5);
t1.add(3);
t1.add(1);
System.out.println(t1);
// [1,3,5]
t1.add(2);
System.out.println(t1);
// [1,2,3]
t1.add(9);
System.out.println(t1);
// [1,2,3]
t1.add(0);
System.out.println(t1);
// [0,1,2]
Assert.assertTrue(3 == t1.size());
Assert.assertEquals(Integer.valueOf(0), t1.first());
}
With the standard API you'd have to do it yourself, i.e. extend one of the sorted set classes and add the logic you want to the add() and addAll() methods. Shouldn't be too hard.
Btw, I don't fully understand your example:
t1.add(9);
// [1,2,3]
Shouldn't the set contain [1,2,9] afterwards?
Edit: I think now I understand: you want to only keep the smallest 3 elements that were added to the set, right?
Edit 2: An example implementation (not optimised) could look like this:
class LimitedSortedSet<E> extends TreeSet<E> {
private int maxSize;
LimitedSortedSet( int maxSize ) {
this.maxSize = maxSize;
}
#Override
public boolean addAll( Collection<? extends E> c ) {
boolean added = super.addAll( c );
if( size() > maxSize ) {
E firstToRemove = (E)toArray( )[maxSize];
removeAll( tailSet( firstToRemove ) );
}
return added;
}
#Override
public boolean add( E o ) {
boolean added = super.add( o );
if( size() > maxSize ) {
E firstToRemove = (E)toArray( )[maxSize];
removeAll( tailSet( firstToRemove ) );
}
return added;
}
}
Note that tailSet() returns the subset including the parameter (if in the set). This means that if you can't calculate the next higher value (doesn't need to be in the set) you'll have to readd that element. This is done in the code above.
If you can calculate the next value, e.g. if you have a set of integers, doing something tailSet( lastElement + 1 ) would be sufficient and you'd not have to readd the last element.
Alternatively you can iterate over the set yourself and remove all elements that follow the last you want to keep.
Another alternative, although that might be more work, would be to check the size before inserting an element and remove accordingly.
Update: as msandiford correctly pointed out, the first element that should be removed is the one at index maxSize. Thus there's no need to readd (re-add?) the last wanted element.
Important note:
As #DieterDP correctly pointed out, the implementation above violates the Collection#add() api contract which states that if a collection refuses to add an element for any reason other than it being a duplicate an excpetion must be thrown.
In the example above the element is first added but might be removed again due to size constraints or other elements might be removed, so this violates the contract.
To fix that you might want to change add() and addAll() to throw exceptions in those cases (or maybe in any case in order to make them unusable) and provide alterante methods to add elements which don't violate any existing api contract.
In any case the above example should be used with care since using it with code that isn't aware of the violations might result in unwanted and hard to debug errors.
I'd say this is a typical application for the decorator pattern, similar to the decorator collections exposed by the Collections class: unmodifiableXXX, synchronizedXXX, singletonXXX etc. I would take Guava's ForwardingSortedSet as base class, and write a class that decorates an existing SortedSet with your required functionality, something like this:
public final class SortedSets {
public <T> SortedSet<T> maximumSize(
final SortedSet<T> original, final int maximumSize){
return new ForwardingSortedSet<T>() {
#Override
protected SortedSet<T> delegate() {
return original;
}
#Override
public boolean add(final T e) {
if(original.size()<maximumSize){
return original.add(e);
}else return false;
}
// implement other methods accordingly
};
}
}
No, there is nothing like that using existing Java Library.
But yes, you can build a one like below using composition. I believe it will be easy.
public class LimitedSet implements SortedSet {
private TreeSet treeSet = new TreeSet();
public boolean add(E e) {
boolean result = treeSet.add(e);
if(treeSet.size() >= expectedSize) {
// remove the one you like ;)
}
return result;
}
// all other methods delegate to the "treeSet"
}
UPDATE
After reading your comment
As you need to remove the last element always:
you can consider maintaining a stack internally
it will increase memory complexity with O(n)
but possible to retrieve the last element with just O(1)... constant time
It should do the trick I believe