Sorry for the very noob question.
Let's suppose I have an enum like so
public enum MyElementType {
TYPE_ONE,
TYPE_TWO,
TYPE_THREE;
}
When I want to loop over this enum, I always see this solution:
for(MyElementType type: MyElementType.values())
{
//do things
}
I wonder if there exist a viable solution with the while loop.
Seraching around I see that Enumeration interface exposes the method
hasMoreElements()
but I don't know how to link the things together.
Any advice?
Why do you want to use a while loop rather than the for-each you more typically see?
In any case, it's pretty simple
Set<MyElementType> elements = EnumSet.allOf(MyElementType.class);
Iterator<MyElementType> it = elements.iterator();
while (it.hasNext()) {
MyElementType el = it.next();
// etc
}
// or
Iterator<MyElementType> it = Arrays.asList(MyElementType.values()).iterator();
Take a look # http://www.javaspecialists.eu/archive/Issue107.html
Related
This might sound like a dumb question, because it might be no other way to do this. After designing my own list, this sort of "issue" came up in multiple occasions. To clarify, I have a problem with returning a cached variable after assigning new value to the original variable. Here's an example:
public T next() {
final Node<T> thisNode = posNode;
posNode = posNode.getNext();
return thisNode.getData();
}
This might seem like a non-issue, but occasionally multiple variables has to be cached before returning a valid value. I do not really like it, because personally I think it reduces the code's readability, especially when caching multiple variables.
Is there another way to write this code while maintaining its functionality? Basically a way to assign a new value to a variable after the return statement:
public T next() {
return posNode.getData();
posNode = posNode.getNext();
}
Thanks! :)
The second way is not possible as the code is not reachable after return. And your first way is the best way far you to achieve what you are looking for and it is not code smell. Often they refer as temp variables. Use them and better convey a message to the code reader by better naming convention. For ex tempPosNode
An elegant (but with some cognitive dissonance) option is a dummy method.
public static <T> T first(T first, Object... theRest) {
return first;
}
public T next() {
return first(posNode.getData(), posNode = posNode.getNext());
}
You can use a finally block to execute it, but it will execute even after exceptions:
public T next() {
try {
return posNode.getData();
} finally {
posNode = posNode.getNext();
}
}
Is there a way to return some value from within a for loop without jumping out of the loop?
I am implementing a static analysis tool where I have to analyze a list of methods (CFGs) in a for loop. The size of CFG list is not known in advance. Each method in the for loop has to return some value. As asked above, is there a way to do it in a loop without breaking the loop? One possible alternative comes in mind is that I can unroll the loop, assuming the maximum list size could be some fixed value. But this does not solve the problem completely. Any help would be appreciated.
code looks like below.
for(CFG cfg: cfgList)
{
val = analyze(cfg);
return val; //I want for loop not to stop here.
}
P.S. I cannot store the values in a list to return values later.
Edit1:
For example, consider following statements.
call method1();
st2;
st3;
...
This method1() can be any of five different methods. For all five possible options, I want to analyze each of them, return their values and analyze rest of the statements accordingly. So, I would analyze these 5 methods as below.
call method1-option1();
st2;
st3;
...
call method1-option2();
st2;
st3;
...
call method1-option3();
st2;
st3;
...
Hope, it helps in understanding the question.
No you can not return value from loop without jumping out of it. According to your need you have to save value in other list and you can return that list after finishing the loop.
In Java 8, you can do:
Iterator<AnalysisResult> lazyAnalysisResults = cfgList.stream()
.map(cfg -> analyze(cfg))
.iterator();
And then the Iterator will supply new analyzed results one at a time, without you needing to collect them all into a list first.
Prior to Java 8, if you want your transformation to be lazy, the best you can do is to implement an Iterator yourself:
public final class AnalyzingIterator extends Iterator<AnalysisResult> {
private final Iterator<CFG> iter;
public AnalyzingIterator(Iterator<CFG> iter) {
this.iter = iter;
}
#Override public boolean hasNext() {
return iter.hasNext();
}
#Override public AnalysisResult next() {
return analyze(iter.next());
}
#Override public boolean remove() {
throw new UnsupportedOperationException();
}
}
If you don't want to store results in a List and return it all together you can use callback mechanism.
Use analyze() to start a new thread passing cfg as well as reference to this. When processing is over make that processing thread call a callback method on your current instance / thread passing the analyzed value. Continue to do whatever you intend to do with this returned value in the callback method. And you don't have to alter your for loop.
So I want to check if anything exists in an array list in an if statement. So instead of
MyArrayList.Contains("blah");
I want something that checks if ANYTHING is in it.
EDIT!:
Found it out!
Thanks for all the help!
Answer:
MyArrayList.isEmpty(){
}
THANKS!
List.isEmpty() is what you are looking for. Refer the docs.
You should to check if your ArrayList is not empty.
You can get achieve this like this code snippet:
if (!arrayList.isEmpty()) {
//your code here...
}
Just check the size of the list. If it's not zero, then there is something in it...
if(arrayList.size() != 0) {
//there is something in the list
}
List.isEmpty():
if (! list.isEmpty()) {
// do something
}
List.size():
if (list.size() > 0) {
// do something
}
Also, keep in mind that most of the time it's preferable to program against the interface (in this case, List) rather than the concrete class (e.g., ArrayList, LinkedList)
You could do it simply like this using .isEmpty():
if(!myArrayList.isEmpty()){
//if your array list has something in it
}
and,
if(myArrayList.isEmpty()){
//if your array list has nothing in it
}
I have a weird problem that I am trying to solve,
I have a enum with a string something like this
public enum Enumm{
Item1("i1"),
Item2("i2");
private String itemText;
private Enumm(String inText){
this.setitemText(inText);
}
// getter and setter for itemText not typing
}
now in the other class I want to check if a string inputString contains either "i1" or "i2" but the problem is I cannot use a loop.
I know I can do this
for(Enumm item: Enumm.values()){
if (inputString.contains(item.getItemText)) {
// do something
}
}
but the constraints of my problem do not allow me to do it this way
I am looking for something like
if(inputString.contains(Enumm.Item1.getItemText||Enumm.Item2.getItemText)){
//do something
}
but is also dynamic such that it finds all the items in the enum
could anyone help me find a solution ?? Thanks in advance.
You could add a static method to your enum called something like findInString(String s) that does the loops over the values() for you and returns a boolean if it finds it. But it depends on why you are trying to avoid the loop. Obviously, this does nothing except squirrels the loop away where you can't see it.
You can make an Item list/array and then parse through the array to check for i1 or i2.
Item[] string = {"i1","i2"}
if(string.contains("i1")||string.contains("i2"))
{
}
Maybe this could help?
List<String> list = Collections.list(enumeration);
boolean b = list.contains("Searchstring");
Under certain situations, I need to evict the oldest element in a Java Set. The set is implemented using a LinkedHashSet, which makes this simple: just get rid of the first element returned by the set's iterator:
Set<Foo> mySet = new LinkedHashSet<Foo>();
// do stuff...
if (mySet.size() >= MAX_SET_SIZE)
{
Iterator<Foo> iter = mySet.iterator();
iter.next();
iter.remove();
}
This is ugly: 3 lines to do something I could do with 1 line if I was using a SortedSet (for other reasons, a SortedSet is not an option here):
if (/*stuff*/)
{
mySet.remove(mySet.first());
}
So is there a cleaner way of doing this, without:
changing the Set implementation, or
writing a static utility method?
Any solutions leveraging Guava are fine.
I am fully aware that sets do not have inherent ordering. I'm asking about removing the first entry as defined by iteration order.
LinkedHashSet is a wrapper for LinkedHashMap which supports a simple "remove oldest" policy. To use it as a Set you can do
Set<String> set = Collections.newSetFromMap(new LinkedHashMap<String, Boolean>(){
protected boolean removeEldestEntry(Map.Entry<String, Boolean> eldest) {
return size() > MAX_ENTRIES;
}
});
if (!mySet.isEmpty())
mySet.remove(mySet.iterator().next());
seems to be less than 3 lines.
You have to synchronize around it of course if your set is shared by multiple threads.
If you really need to do this at several places in your code, just write a static method.
The other solutions proposed are often slower since they imply calling the Set.remove(Object) method instead of the Iterator.remove() method.
#Nullable
public static <T> T removeFirst(Collection<? extends T> c) {
Iterator<? extends T> it = c.iterator();
if (!it.hasNext()) { return null; }
T removed = it.next();
it.remove();
return removed;
}
With guava:
if (!set.isEmpty() && set.size() >= MAX_SET_SIZE) {
set.remove(Iterables.get(set, 0));
}
I will also suggest an alternative approach. Yes, it it changing the implementation, but not drastically: extend LinkedHashSet and have that condition in the add method:
public LimitedLinkedHashSet<E> extends LinkedHashSet<E> {
public void add(E element) {
super.add(element);
// your 5-line logic from above or my solution with guava
}
}
It's still 5 line, but it is invisible to the code that's using it. And since this is actually a specific behaviour of the set, it is logical to have it within the set.
I think the way you're doing it is fine. Is this something you do often enough to be worth finding a shorter way? You could do basically the same thing with Guava like this:
Iterables.removeIf(Iterables.limit(mySet, 1), Predicates.alwaysTrue());
That adds the small overhead of wrapping the set and its iterator for limiting and then calling the alwaysTrue() predicate once... doesn't seem especially worth it to me though.
Edit: To put what I said in a comment in an answer, you could create a SetMultimap that automatically restricts the number of values it can have per key like this:
SetMultimap<K, V> multimap = Multimaps.newSetMultimap(map,
new Supplier<Set<V>>() {
public Set<V> get() {
return Sets.newSetFromMap(new LinkedHashMap<V, Boolean>() {
#Override protected boolean removeEldestEntry(Entry<K, V> eldestEntry) {
return size() > MAX_SIZE;
}
});
}
});
Quick and dirty one-line solution: mySet.remove(mySet.toArray(new Foo[mySet.size()])[0]) ;)
However, I'd still go for the iterator solution, since this would be more readable and should also be faster.
Edit: I'd go for Mike Samuel's solution. :)