Sorting an ArrayList by two different properties - arraylist

So I have a HashMap<String, Integer> which represents the number of times a certain word has been encountered in a sentence. What I want to do is put all the words in an ArrayList<String>, sorted first by the number of times a word has been encountered, and then break ties by alphabetical order. How would I go about doing that? My code looks something like this:
public class MyClass {
private HashMap<String, Integer> map;
public ArrayList<String> Order() {
ArrayList<String> temp = new ArrayList<>();
(...)
}

You'll need to use a custom comparator. For the comparison method, you'll need to return a negative value if the first argument should be treated as less than the second, 0 if they are equal, and a positive value if the first argument should be treated as greater than the second.
Note that this sorts the ArrayList in descending order according to the integer value
import java.util.Comparator;
import java.util.HashMap;
public class CustomComparator implements Comparator<String>
{
HashMap<String, Integer> map;
public CustomComparator(HashMap<String, Integer> comparisonMap)
{
map = comparisonMap;
}
#Override
public int compare(String s1, String s2)
{
int count1 = map.get(s1);
int count2 = map.get(s2);
if (count1 == count2)
return s1.compareTo(s2);
return count2 - count1;
}
}
Two steps to create and sort the ArrayList:
First, add every key from the HashMap to the ArrayList
ArrayList<String> result = new ArrayList<String>(map.size());
result.addAll(map.keySet());
Then, sort the ArrayList using the custom comparator:
Collections.sort(result, new CustomComparator(map));

Related

Java query an ArrayList of predefined object

I have an ArrayList (inputList) that parse this data:
id,name,quantity
1,foo,10
2,bar,20
3,foo,10
4,bar,10
5,qwerty,1
Code:
...
List<FooRow> inputList = new ArrayList<FooRow>();
inputList = br.lines().map(mapToFooRow).collect(Collectors.toList());
...
public class FooRow{
private Integer id;
private String name;
private Integer value;
}
I want to create a collectors that return me a list with the count of value grouped by name:
name,value
foo,20
bar,30
qwerty,1
How can I create a class Collectors to do this in the lambda expression?
Thanks.
You can use Collectors.groupingBy and Collectors.summingInt:
Map<String, Integer> result =
inputList.stream()
.collect(Collectors.groupingBy(
FooRow::getName, Collectors.summingInt(FooRow::getValue)));

Jackson one item parse

I'm trying to parse openweathermap.org api
WeatheModel.java
public class WeatherModel {
private ListDays[] listDays;
#JsonProperty("list")
public ListDays[] getListDays() {
return listDays;
}
and two classes here http://pastebin.com/vySPfRSS
Main.java
public class Main {
public static final String WEATHER = "JSON from http://api.openweathermap.org/data/2.5/forecast/daily?q=London&mode=json&units=metric&cnt=7"
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
WeatherModel rootNode = mapper.readValue(WEATHER, WeatherModel.class);
How to get one (now it a list of 7 items ) item from WeatherModel?
Simply use the index to access object from an array.
ListDays[] listDays = rootNode.getListDays();
ListDays first = listDays[0];
ListDays second = listDays[1];
Arrays are sequences of objects and in the case above you describe an array of 7 ListDays. The first object uses index 0, the second object uses index 1 and so on. The [0] simply means that you retrieve the first object from the array. The length of the array can be determined by invoking listDays.length.
To loop through all of the elements you can use a for-loop.
for (ListDays l : listDays) {
// Here you have access to one ListDays-object. It is called l.
l.doStuff...
}

Trouble employing BeanItemContainer and TreeTable in Vaadin

I have reviewed multiple examples for how to construct a TreeTable from from a Container datasource and just adding items iterating over an Object[][]. Still I'm stuck for my use case.
I have a bean like so...
public class DSRUpdateHourlyDTO implements UniquelyKeyed<AssetOwnedHourlyLocatableId>, Serializable
{
private static final long serialVersionUID = 1L;
private final AssetOwnedHourlyLocatableId id = new AssetOwnedHourlyLocatableId();
private String commitStatus;
private BigDecimal economicMax;
private BigDecimal economicMin;
public void setCommitStatus(String commitStatus) { this.commitStatus = commitStatus; }
public void setEconomicMax(BigDecimal economicMax) { this.economicMax = economicMax; }
public void setEconomicMin(BigDecimal economicMin) { this.economicMin = economicMin; }
public String getCommitStatus() { return commitStatus; }
public BigDecimal getEconomicMax() { return economicMax; }
public BigDecimal getEconomicMin() { return economicMin; }
public AssetOwnedHourlyLocatableId getId() { return id; }
#Override
public AssetOwnedHourlyLocatableId getKey() {
return getId();
}
}
The AssetOwnedHourlyLocatableId is a compound id. It looks like...
public class AssetOwnedHourlyLocatableId implements Serializable, AssetOwned, HasHour, Locatable,
UniquelyKeyed<AssetOwnedHourlyLocatableId> {
private static final long serialVersionUID = 1L;
private String location;
private String hour;
private String assetOwner;
#Override
public String getLocation() {
return location;
}
#Override
public void setLocation(final String location) {
this.location = location;
}
#Override
public String getHour() {
return hour;
}
#Override
public void setHour(final String hour) {
this.hour = hour;
}
#Override
public String getAssetOwner() {
return assetOwner;
}
#Override
public void setAssetOwner(final String assetOwner) {
this.assetOwner = assetOwner;
}
}
I want to generate a grid where the hours are pivoted into column headers and the location is the only other additional column header.
E.g.,
Location 1 2 3 4 5 6 ... 24
would be the column headers.
Underneath each column you might see...
> L1
> Commit Status Status1 .... Status24
> Eco Min EcoMin1 .... EcoMin24
> Eco Max EcoMax1 .... EcoMax24
> L2
> Commit Status Status1 .... Status24
> Eco Min EcoMin1 .... EcoMin24
> Eco Max EcoMax1 .... EcoMax24
So, if I'm provided a List<DSRUpdateHourlyDTO> I want to convert it into the presentation format described above.
What would be the best way to do this?
I have a few additional functional requirements.
I want to be able to toggle between read-only and editable views of the same table.
I want to be able to complete a round-trip to a datasource (e.g., JPAContainerSource).
I (will eventually) want to filter items by any part of the compound id.
My challenge is in the adaptation. I well understand the simple use case where I could take the list and simply splat it into a BeanItemContainer and use addNestedContainerProperty and setVisibleColumns. Pivoting properties into columns seems to be what's stumping me.
As it turns out this was an ill-conceived question.
For data entry purposes, one could use a BeanItemContainer and have the columns include nested container property hour from the composite id and instead of a TreeTable, use a Table that has commitStatus, ecoMin and ecoMax as columns. Limitation: you'd only ever query for / submit one assetOwner and location's worth of data.
As for display, where you don't care to filter one assetOwner and location's worth of data, you could pivot the hour info as originally described. You could just convert the original bean into another bean suitable for display (where each hour is its own column).

Delete elements from a List using iterator

There is a List<Integer> tabulist that contains values [2,0,5].
Also, there is a List this.getRoutes() which contains keys [0,1,2,3,4,5].
I need to delete elements [2,0,5] from this.getRoutes().
So, as a result I must get the following entries in this.getRoutes():
[1,3,4]
Here is my code:
iter = this.getRoutes().iterator();
while(iter.hasNext())
{
Route r = iter.next();
if (tabulist.contains(r.getRouteKey()))
{
iter.remove();
}
}
The problem is that r.getRouteKey() is always 0. Therefore, I am always deleting the first elements from this.getRoutes(). I don't understand why the iterator does not move to [1,2,3,4,5].
How to solve this issue? Maybe I should also delete values from tabulist?
I didn't test my code, but here are 3 variations on the theme. You should test them in case I made a mistake, but they give an idea of the general idea.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class Class1
{
public static List<int> RemoveItems1(List<int> OriginalValues, List<int> ValuesToRemove)
{
List<int> result = new List<int>();
foreach (object item_loopVariable in OriginalValues) {
item = item_loopVariable;
if ((!ValuesToRemove.Contains(item))) {
result.Add(item);
}
}
return result;
}
public static List<int> RemoveItems2(List<int> OriginalValues, List<int> ValuesToRemove)
{
List<int> result = OriginalValues;
foreach (object item_loopVariable in ValuesToRemove) {
item = item_loopVariable;
if ((OriginalValues.Contains(item))) {
result.Remove(item);
}
}
return result;
}
public static List<int> RemoveItems3(List<int> OriginalValues, List<int> ValuesToRemove)
{
List<int> result = OriginalValues;
foreach (object item_loopVariable in from item1 in ValuesToRemovewhere (OriginalValues.Contains(item1))) {
item = item_loopVariable;
result.Remove(item);
}
return result;
}
}
The first one adds only elements to get to a result. Like I said in my comment.
The second one removes elements from a result that is set to the parameter Originalvalues. The last one is basically the same as number two, but uses LINQ.
I'm using static methods because then this can be used in any situation and you don't need to instantiate a class to do this. Which adds extra unnecessary code.

How to iterate through a PORTION of a TreeMap?

I'm doing an assignment where I have to search through keys in a TreeMap (that are mapped to files that they are found in. Basically, this TreeMap is an Inverted Index) that start with a query word that we specify to the program in a query file. However, for efficiency purposes, my professor does not want is to iterate through ALL the keys in the TreeMap when we look for keys that start with the query words, rather she wants us to iterate through only the keys that we need to iterate through. For example, if the query word starts with C, then we should only iterate through the keys that start with C. Any ideas on how to approach this?
Use the TreeMap's subMap() method to obtain a SortedMap that contains only the range of keys that you want to examine. Then iterate over that SortedMap.
Here is the basic implementation of what #ottomeister suggested:
public class Tester{
public static void main(String a[]){
TreeMap<CustomObject,String> tm = new TreeMap<CustomObject,String>();
tm.put(new CustomObject(4,"abc"),"abc");
tm.put(new CustomObject(7,"bcd"),"bcd");
tm.put(new CustomObject(25,"cde"),"cde");
tm.put(new CustomObject(18,"def"),"def");
tm.put(new CustomObject(2,"efg"),"efg");
tm.put(new CustomObject(8,"fgh"),"fgh");
tm.put(new CustomObject(3,"aab"),"aab");
tm.put(new CustomObject(13,"aab"),"abb");
Map<CustomObject, String> sub = tm.subMap(new CustomObject(9,""),new CustomObject(20,""));
for(Map.Entry<CustomObject,String> entry : sub.entrySet()) {
CustomObject key = entry.getKey();
String value = entry.getValue();
System.out.println(key.getId() + " => " + value);
}
}
}
class CustomObject implements Comparable<CustomObject>{
private int id;
private String Name;
CustomObject(int id, String Name){
this.id = id;
this.Name = Name;
}
#Override
public int compareTo(#NotNull CustomObject o) {
return this.id - o.id;
}
public int getId(){
return this.id;
}
}
output:
13 => abb
18 => def