Descending Sorting of an ArrayList of Object - sorting

I need to sort this ArrayObject :
public ArrayList<WPPost> posts;
on descending :
posts.get(i).getRating()
I have tried with HashMaps, LinkedHashMaps, I haven't found anything. What's the best solution ?

I think that one of the best solutions is the use of Collections.sort
Collections.sort(posts, new Comparator<WPPost>() {
#Override
public int compare(WPPost o1, WPPost o2) {
return o2.getRating() - o1.getRating();
}
});
In some implemetations Collectios sort use merge sort algorithm, that will give you a O(log n) complexity.

Related

A algorithm to track the status of a number

To design a API,
get(), it will return the random number, also the number should not duplicate, means it always be unique.
put(randomvalue), it will put back the generated random number from get(), if put back, get() function can reuse this number as output.
It has to be efficient, no too much resource is highly used.
Is there any way to implement this algorithm? It is not recommended to use hashmap, because if this API generate for billions of requests, saving the generated the random number still use too much space.
I could no work out this algorithm, please help give a clue, thanks in advance!
I cannot think of any solution without extra space. With space, one option could be to use TreeMap, firstly add all the elements in treeMap with as false. When element is accessed, mark as true. Similarly for put, change the value to false.
Code snippet below...
public class RandomNumber {
public static final int SIZE = 100000;
public static Random rand;
public static TreeMap<Integer, Boolean> treeMap;
public RandomNumber() {
rand = new Random();
treeMap = new TreeMap<>();
}
static public int getRandom() {
while (true) {
int random = rand.nextInt(SIZE);
if (!treeMap.get(random)) {
treeMap.put(random, true);
return random;
}
}
}
static public void putRandom(int number) {
treeMap.put(number, false);
}
}

Why does Dart's default sort implementation beat my key-sorter?

I thought I was being clever I implemented a sorter which does not use a comparing function that simply recalculates the sort-score of the compared elements each iteration, but rather calculates the scores (I call them keys) once and caches them. For me that seemed to be contraire to what the dart default implementation (or for that matter, also the Java implementation) does.
Anyway, here is my implementation:
class KeySorter<V, K extends Comparable> {
List<V> list;
KeySorter(this.list);
List<V> sort(K keyFn(V)) {
Map<V, K> keys = {};
list.sort((e1, e2) {
var e1Key = keys.putIfAbsent(e1, () => keyFn(e1)),
e2Key = keys.putIfAbsent(e2, () => keyFn(e2));
return e1Key.compareTo(e2Key);
});
return list;
}
}
And that's the benchmark:
https://gist.github.com/Gregoor/547c0451c4fa527dd85c
The default implementation beats mine by a factor of 4. How comes?
As mentioned in the comments, caching only makes sense if it takes less time to create and look up the cache than to calculate the result from scratch.
Your implementation also artificially slows down the cache look-up by using putIfAbsent unnecessarily. Replacing this with an initial cache population followed by a direct key lookup reduces the performance difference to only a factor of 2:
List<V> sort(K keyFn(V)) {
Map<V, K> keys = {};
list.forEach((e) => keys[e] = keyFn(e));
list.sort((e1, e2) {
return keys[e1].compareTo(keys[e2]);
});
return list;
}

LINQ - Sorting a custom list

I want to do the same as explained here:
Sorting a list using Lambda/Linq to objects
that is:
public enum SortDirection { Ascending, Descending }
public void Sort<TKey>(ref List<Employee> list,
Func<Employee, TKey> sorter, SortDirection direction)
{
if (direction == SortDirection.Ascending)
list = list.OrderBy(sorter);
else
list = list.OrderByDescending(sorter);
}
to call it he said to do:
Sort(ref employees, e => e.DOB, SortDirection.Descending);
but I do not understand what TKey is refering to and as I can see in the call it is missed the generic TKey.
Could you explain me what is TKey and how to use it?
I suppose I can use another name for the method, it is not necessary to be Sort, right?
thanks!
You sort by the key which is of type TKey and must implement IComparable<TKey>. For instance:
// key: Firstname
// TKey: string (which is IComparable<String>
list.OrderBy(person => person.Firstname);
The above code sorts by firstname, which is what you define using the sorter. And yes, you can give your method any name you like. It does not have to be named Sort.
Improvement Suggestion (indirectly related to the question)
instead of changing list and passing it as a reference I'd suggest you to consider the following implementation:
public IOrderedEnumerable<Employee> Sort<TKey>(IEnumerable<Employee> list, Func<Employee, TKey> sorter, SortDirection direction);
{
IOrderedEnumerable<Employee> result;
if (direction == SortDirection.Ascending)
result = list.OrderBy(sorter);
else
result = list.OrderByDescending(sorter);
return result;
}
You could then return a new ordered enumerable of Employee objects instead of changing the old one and use any enumerable instead of List object only. This gives you more flexibility and is closer to the LINQ implementation which people tend to be used to.

How to select objects from a list that has a property that matches an item in another list?

Hard question to understand perhaps, but let me explain. I have a List of Channel-objects, that all have a ChannelId property (int). I also have a different List (int) - SelectedChannelIds, that contains a subset of the ChannelId-s.
I want to select (through LINQ?) all the Channel-objects that has a ChannelId-property matching one in the second List.
in other words, I have the following structure:
public class Lists
{
public List<Channel> AllChannels = ChannelController.GetAllChannels();
public List<int> SelectedChannelIds = ChannelController.GetSelectedChannels();
public List<Channel> SelectedChannels; // = ?????
}
public class Channel
{
// ...
public int ChannelId { get; set; }
// ...
}
Any ideas on what that LINQ query would look like? Or is there a more effective way? I'm coding for the Windows Phone 7, fyi.
You can use List.Contains in a Where clause:
public Lists()
{
SelectedChannels = AllChannels
.Where(channel => SelectedChannelIds.Contains(channel.ChannelId))
.ToList();
}
Note that it would be more efficient if you used a HashSet<int> instead of a List<int> for the SelectedChannelIds. Changing to a HashSet will improve the performance from O(n2) to O(n), though if your list is always quite small this may not be a significant issue.
SelectedChannels = new List<Channel>(AllChannels.Where(c => SelectedChannelIds.Contains(c.ChannelId)));

String set implementation

I have to implement a set ADT for a pair of strings. The interface I want is (in Java):
public interface StringSet {
void add(String a, String b);
boolean contains(String a, String b);
void remove(String a, String b);
}
The data access pattern has the following properties:
The contains operation is far more frequent that the add and remove ones.
More often that not, contains returns true i.e. the search is successful
A simple implementation I can think of is to use a two-level hashtable, i.e. HashMap<String, HashMap<String, Boolean>>. But this datastructure makes no use of the two peculiarities of the access pattern. I am wondering if there is something more efficient than the hashtable, maybe by leveraging the access pattern peculiarities.
Personally, I would design this in terms of a standard Set<> interface:
public class StringPair {
public StringPair(String a, String b) {
a_ = a;
b_ = b;
hash_ = (a_ + b_).hashCode();
}
public boolean equals(StringPair pair) {
return (a_.equals(pair.a_) && b_.equals(pair.b_));
}
#Override
public boolean equals(Object obj) {
if (obj instanceof StringPair) {
return equals((StringPair) obj);
}
return false;
}
#Override
public int hashCode() {
return hash_;
}
private String a_;
private String b_;
private int hash_;
}
public class StringSetImpl implements StringSet {
public StringSetImpl(SetFactory factory) {
pair_set_ = factory.createSet<StringPair>();
}
// ...
private Set<StringPair> pair_set_ = null;
}
Then you could leave it up to the user of StringSetImpl to use the preferred Set type. If you are attempting to optimize access, though, it's hard to do better than a HashSet<> (at least with respect to runtime complexity), given that access is O(1), whereas tree-based sets have O(log N) access times.
That contains() usually returns true may make it worth considering a Bloom filter, although this would require that some number of false positives for contains() are allowed (don't know if that is the case).
Edit
To avoid the extra allocation, you can do something like this, which is similar to your two-level approach, except using a set rather than a map for the second level:
public class StringSetImpl implements StringSet {
public StringSetImpl() {
elements_ = new HashMap<String, Set<String>>();
}
public boolean contains(String a, String b) {
if (!elements_.containsKey(a)) {
return false;
}
Set<String> set = elements_.get(a);
if (set == null) {
return false;
}
return set.contains(b);
}
public void add(String a, String b) {
if (!elements_.containsKey(a) || elements_.get(a) == null) {
elements_.put(a, new HashSet<String>());
}
elements_.get(a).add(b);
}
public void remove(String a, String b) {
if (!elements_.containsKey(a)) {
return;
}
HashSet<String> set = elements_.get(a);
if (set == null) {
elements_.remove(a);
return a;
}
set.remove(b);
if (set.empty()) {
elements_.remove(a);
}
}
private Map<String, Set<String>> elements_ = null;
}
Since it's 4:20 AM where I'm located, the above is definitely not my best work (too tired to refresh myself on the treatment of null by these different collections types), but it sketches the approach.
Do not use normal trees (most standard library data structures) for this. There is one simple assumption, which will hurt you in this case:
The normal O(log(n)) calculation of operations on trees assume that comparisons are in O(1). This is true for integers and most other keys, but not for strings. In case of strings each comparison is on O(k) where k is the length of the string. This makes all operations dependent on the length, which will most likely hurt you if you need to be fast and is easily overlooked.
Especially if you most often return true there will be k comparisons for each string at each level, so with this access pattern you will experience the full drawback of strings in trees.
Your access pattern is easily handled by a Trie. Testing if a string is contained is in O(k) worst case (not average case as in a hash map). Adding a string is is also in O(k). Since you are storing two strings I would suggest, you don't index your trie by characters, but rather by some larger type, so you can add two special index values. One value for the end of the first string, and one value for the end of both strings.
In your case using these two extra symbols would also allow for simple removal: Just delete the final node containing the end symbol and your string will not be found anymore. You will waste some memory, because you still have the strings in your structure that have been deleted. In case this is a problem you could keep track of the number of deleted strings and rebuild your trie in case this get's to bad.
P.s. A trie can be thought of as a combination of a tree and several hashtables, so this gives you the best of both data structures.
I'd second the approach of Michael Aaron Safyan to use a StringPair type. Perhaps with a more specific name, or as a generic tuple type: Tuple<A,B> instantiated to Tuple<String,String>. But I would strongly suggest to use one of the provided set implementations, either a HashSet or a TreeSet.
Red-Black Tree implementation of the set would be a good option. C++ STL is implemented in Red-Black Tree

Resources