What would be the most efficent to check if something is on a list of enums? I've looked around for a while and it wasn't very clear. Arrays don't have a contains() function and hashmaps are key:value.
Something like:
if(enumlist.contains(foo.enum())){
// Do something
}
Use List#indexOf().
if (enumList.indexOf(foo) > -1) {
// go crazy
}
Alternately, you can use the (extremely efficient) EnumSet data structure to store the objects — if you're okay with not being able to store duplicate elements.
if (enumSet.contains(foo)) {
// just, like, whatever, man
}
EnumSet has a suitable contains() method.
Addendum: Using this example, the following prints true.
System.out.println(Resolution.deluxe.contains(Resolution.RES_256));
Related
I have a list of Strings and I want to perform the same operation on all of the Strings in the list.
Is it possible without performing a loop?
Well something's got to loop, somewhere - if you want to abstract that into your own method, you could do so, but I don't believe there's anything built into the framework.
Guava has various methods in Iterables to perform projections etc, but if you want to modify the list on each step, I'm not sure there's any support for that. Again, you could write your own method (extremely simply) should you wish to.
When Java eventually gets closures, this sort of thing will become a lot more reasonable - at the moment, specifying the "something" operation is often more effort than it's worth compared with hard-coding the loop, unfortunately.
You could do it recursively, but I don't see why you'd want to. You may be able to find something similar to Python's map function (which, behind the scenes, would either be a loop or a recursive method)
Also note that strings are immutable - so you'll have to create 'copies' anyway.
No. You must loop through the list.
for(String s:yourlist){
dooperation(s);
}
Why do you not want to perform a loop?
If it's computational complexity, then no, it's unavoidable. All methods will essentially boil down to iterating over every item in the list.
If it's because you want something cleaner, then the answer depends on what you think is cleaner. There are various libraries that add some form of functional map, which would end up with something like:
map(list, new Mapper<String, String>() {
public String map(String input) {
return doSomethingToString(input);
}
);
This is obviously more long winded and complex than a simple loop
for (int i = 0; i < list.size(); i += 1) {
list[i] = doSomethingToString(list[i]);
}
But it does offer reusability.
map(list, new DoSomethingToStringMapper());
map(otherlist, new DoSomethingToStringMapper());
But probably you don't need this. A simple loop would be the way to go.
You could use apache commons util.
sorry, you have to iterate through the list somehow, and the best way is in a loop.
Depending on what you mean by no loop, this may interest you:
a map function for java.
http://www.gubatron.com/blog/2010/08/31/map-function-in-java/
...there's still a loop down inside of it.
In Java you'll need to iterate over the elements in the Collection and apply the method. I know Groovy offers the * syntax to do this. You could create an interface for your functions e.g. with an apply method and write a method which takes your Collection and the interface containing the function to apply if you want to add some general API for doing this. But you'll need the iteration somewhere!
Use divide and conquer with multithreaded traversal. Make sure you return new/immutable transformed collection objects (if you want to avoid concurrency issues), and then you can finally merge (may be using another thread which will wake up after all the worker threads finished transformer tasks on the divided lists?).
If lack of memory in creating these intermediate collections, then synchronize on your source collection. Thats the best you can do.
No you have to use a loop for that.
You have to perform the operation on each reference variable to the Strings in the List, so a loop is required.
If its at the List level, obviously there are some operations (removeAll, etc.).
The java API provides special class to store and manipulate group of objects. One Such Class is Arraylist
Note that Arraylist class is in java.util.ArrayList
Create an ArrayList as you would any objects.
import java.util.ArrayList;
//..
ArrayList ajay = new ArrayList();
Here
ArrayList -> Class
ajay -> object
You can optionally specify a capacity and type of objects the Arraylist will hold:
ArrayList ajay<String> = new ArrayList<String>(10);
The Arraylist class provides a number of useful methods for manipulating objects..
The add() method adds new objects to the ArrayList.And remove() method remove objects from the List..
Sample code:
import java.util.ArrayList;
public class MyClass {
public static void main(String[ ] args) {
ArrayList<String> ajay = new ArrayList<String>();
ajay.add("Red");
ajay.add("Blue");
ajay.add("Green");
ajay.add("Orange");
ajay.remove("Green");
System.out.println(colors);
}
}
Output for this Code:
[Red,Blue,Orange]
Accepted answer link is broken and solution offered is deprecated:
CollectionUtils::forAllDo
#Deprecated
public static <T,C extends Closure<? super T>> C forAllDo(Iterable<T> collection, C closure)
Deprecated. since 4.1, use IterableUtils.forEach(Iterable, Closure) instead
Executes the given closure on each element in the collection.
If the input collection or closure is null, there is no change made.
You can use IterableUtils::forEach(Closure c)
Applies the closure to each element of the provided iterable.
I have an ArrayList of video resolutions that looks like this:
"1024x768", "800x600", "1280x1024", etc
I want to sort it based on numeric value in first part of string.
Ie, the above would sort out to look like this:
"800x600","1024x768","1280x1024"
Is there a quick and dirty way to do this, by that I mean in less then 2-3 lines of code? If not, what would be the proper way? The values I get are from an object not my own. It does have a getWidth() and getHeight() methods that return ints.
If the objects in the array are Resolution instances with getWidth methods then you can use a Comparator to sort on those:
Collections.sort(resolutions, new Comparator {
public int compare(Resolution r1, Resolution r2) {
return Integer.valueOf(r1.getWidth()).compareTo(Integer.valueOf(r2.getWidth()));
}
});
The proper way is to write a Comparator implementation that operates on Strings, except that it parses up to the first non-numeric character. It then creates an int out of that and compares the ints.
You can then pass an instance of that Comparator into Collections.sort() along with your List.
Use a custom Comparator to sort the ArrayList via the Collections api.
Collections.sort(resolutionArrayList, new ResolutionComparator())
Using a Comparator will work, but will get slow if you have lots of values because it will parse each String more than once.
An alternative is to add each value to a TreeMap, with the number you want as the key, i.e., Integer.valueOf(s.substring(0,s.indexOf('x'))), then create a new ArrayList from the sorted values in treeMap.values().
The solution suggested by Shadwell in his answer is correct and idiomatic.
But if you're looking for a more concise solution, then I'd advise you use lambdaj which will enable you to write code like:
List<Resolution> sortedResolutions = sort(resolutions, on(Resolution.class).getWidth());
Suppose I have a map in Java which looks like this:
{
39:"39 to 41",
41:"41 to 43",
43:"43 to 45",
45:">=45"
}
If the keys are in sorted order(either using treemap or linkedhashmap).Now if i try to get a value which is >=39 and <41.Then I should get the String "39 to 41".How do I do this efficiently?
It looks like you want more than a SortedMap; you want a NavigableMap! Specifically you can use the floorKey operation.
Here's an example:
NavigableMap<Integer,String> map =
new TreeMap<Integer, String>();
map.put(0, "Kid");
map.put(11, "Teens");
map.put(20, "Twenties");
map.put(30, "Thirties");
map.put(40, "Forties");
map.put(50, "Senior");
map.put(100, "OMG OMG OMG!");
System.out.println(map.get(map.floorKey(13))); // Teens
System.out.println(map.get(map.floorKey(29))); // Twenties
System.out.println(map.get(map.floorKey(30))); // Thirties
System.out.println(map.floorEntry(42).getValue()); // Forties
System.out.println(map.get(map.floorKey(666))); // OMG OMG OMG!
Note that there are also ceilingKey, lowerKey, higherKey, and also …Entry instead of …Key operations as well which returns a Map.Entry<K,V> instead of just the K.
Try Java 6 java.util.NavigableMap. http://download.oracle.com/javase/6/docs/api/java/util/NavigableMap.html.
In special use floorKey/floorEntry.
By example: floorKey(40) should return 39. floorEntry would return the value you are looking for.
With a sorted map, you could do something like that:
SortedMap<Integer,String> head = map.headMap(value+1);
if (head.isEmpty()) {
return null;
} else {
return head.get(head.lastKey());
}
I'm not sure that's going to be easy. One suggestion would be to "fill in the gaps", ie put in a value 40->"39 to 41" etc etc. I suppose that will only be possible if you know the whole range of numbers possible in the map.
Or mabybe something that overrides the get to check to see if the value is in the map, and expanding out until it finds something. I'm not sure that's going to be possible in its current guise, as you'd have to end up parsing the value strings.
You can recursively look for lower boundary.
public String descriptionFor(int value) {
String description = map.get(value);
return description == null ? descriptionFor(value--) : description;
}
You will need to have a minimum boundary.
You'd have to implement such a map yourself, I believe. You're right that it would have to be sorted; the implementation of get would have to iterate through the keys until it finds the largest key that is less than or equal to the argument.
If you subclass TreeMap it would initially appear that you can get this working via simply overriding the get() method. However, to maintain as much of the Map contract as possible you'll have to override other methods for consistency.
And what about e.g. containsKey()? Does your main contain a mapping for 40? If you return false, then a client can decide not to call get() based on this information; for these reason (and the formal definition) you have to return true. But then it makes it hard to determine whether the map "really contains" a given mapping; if you're looking to do something such as update without overwriting anything that already exists.
The remove() method might be tricky too. From my reading of the interface,
// Calling map.remove "Removes the mapping for a key from this map if it is present."
map.remove(x);
// Now that the mapping is removed, I believe the following must hold
assert map.get(x) == null;
assert map.containsKey(x);
Acting consistently here would be very tricky. If you have a mapping from 35-40 for example, and you call remove(38), then as I understand it you'd have to return null for any subsequent gets for the key 38, but return the aforementioned mapping for keys 35-37 or 39-40.
So while you can make a start on this by overriding TreeMap, perhaps the whole concept of Map is not quite what you want here. Unless you need this behaviour to slot into existing methods that take Map, it might be easier to create it yourself as a distinct class since it's not quite a Map, the way you're defining it.
I want to create a large (~300,000 entries) List of self defined objects of the class Drug.
Every Drug has an ID and I want to be able to search the Drugs in logarithmic time via that ID.
What kind of List do I have to use?
How do I declare that it should be searchable via the ID?
The various implementations of the Map interface should do what you want.
Just remember to override the hashCode() method of your Drug class if you plan to use a HashMap.
public class Drug implements Comparable<Drug> {
public int compareTo(Drug o) {
return this.id.compareTo(o.getId());
}
}
Then in your List you can use binarySearch
List<Drug> drugList; <--- List of all drugs
Drug drugToSearchFor; <---- The drug that you want to search for, containing the id
// Sort before search
Collections.sort(drugList);
int index = Collections.binarySearch(drugList, drugToSearchFor);
if (index >= 0) {
return true;
} else {
return false;
}
Wouldn't you use TreeMap instead of List using the ID as your Key?
If searching by a key is important for you, then you probably need to use a Map and not a List. From the Java Collections Trail:
The three general-purpose Map
implementations are HashMap, TreeMap
and LinkedHashMap. If you need
SortedMap operations or key-ordered
Collection-view iteration, use
TreeMap; if you want maximum speed and
don't care about iteration order, use
HashMap; if you want near-HashMap
performance and insertion-order
iteration, use LinkedHashMap.
Due to the high number of entries you might consider to use a database instead of holding everything in memory.
If you still want to keep it in memory you might have a look at b-trees.
You could use any list, and as long as it is sorted you can use a binary search.
But I would use a Map which searches in O(1).
I know I am pretty redundant with this statement, but as everybody said isnt this exactly the case for a Map ?
I have the following problem in my Data Structures and Problem Solving using Java book:
Write a routine that uses the Collections API to print out the items in any Collection in reverse order. Do not use a ListIterator.
I'm not putting it up here because I want somebody to do my homework, I just can't seem to understand exactly what it is asking for me to code!
When it asks me to write a 'routine', is it looking for a single method? I don't really understand how I can make a single method work for all of the various types of Collections (linked list, queue, stack).
If anybody could guide me in the right direction, I would greatly appreciate it.
Regardless from the question not making much sense as half of the collections have no gstable ordering of have fixed-ordering (i.e. TreeSet or PriorityQueue), you can use the following statement for printing the contents of a collection in reverse-natural order:
List temp = new ArrayList(src);
Collections.reverse(temp);
System.out.println(temp);
I essence you create an array list as lists are the only structure that can be arbitrarily reordered. You pass the src collection to the constructor which initializes the list withj the contents of the src in the collection natural order. Then you pass the list to the Collections.reverse() method which reverses the list and finally you print it.
First, I believe it is asking you to write a method. Like:
void printReverseList(Collection col) {}
Then there are many ways to do this. For example, only using the Collection API, use the toArray method and use a for loop to print out all the items from the end. Make sense?
As for the various classes using the Collection interface, it will automatically work for all of those since they must implement the interface (provided they implement it in a sane way;).
Well you could have a routine that delegates to other routines based on the input type, however I'm not sure there is a generic enough collection type that can be encompassed into one argument. I guess you could just use method overloading (having multiple methods with the same name, but accept different args).
That could technically count as 1 routine (all have the same name).
I don't know much Java, but considering the "Collections API" i imagine all those objects implement an interface you could iterate through someway. i suppose they all could have an itemAtIndex( int index ) and length() or similar method you could use.
You might want to read this.
Isn't there a base Collection class?
Probably worth looking here as a starting point: Collections.