How to create an associative list in Java? - java

I am trying to have a user enter a String to search for a value in a list. This works fine, but I also want the String to have a numeric value. This way I can get the certain item in the lists price. I tried:
public List<String, double>
However this always gives me an error. How can I store strings and their corresponding numeric value?

Use a Map.
Map<String, Double> someMap = new HashMap<String, Double>();
Then, you can use Map#put(K, V) and Map#get(K) to put and get values.
Check out the Map documentation as well.
From Java 7 onwards, you can omit the generic type within the constructor's declaration:
Map<String, Double> someMap = new HashMap<>();

Are you only storing a String and a Double, or will you eventually need to store more information about each object?
For example, you're talking about storing a name and a price. If this is for a shopping-like program, you would probably be best to store all the information for each product in a new class, and then store the class in the HashMap. For example..
// Class for your product and all related information...
public class Product {
String name;
double price;
String color;
double weight;
public Product(String name, double price, String color, double weight){
this.name = name;
this.price = price;
this.color = color;
this.weight = weight;
}
}
// Now add each Product to a HashMap (in your main class)...
HashMap<String,Product> products = new HashMap<String,Product>();
products.put("Cheese", new Product("Cheese",1.10,"Yellow",0.5);
products.put("Milk", new Product("Milk",2.0,"White",1.5);
You will then be able to query the HashMap for "Cheese" and you'll get the Product and and all the information for it...
Product cheese = products.get("Cheese");
double price = cheese.getPrice();

Related

How do you create a method in objects that finds the highest number using hashmap?

I'm new with hashmap and I'm trying to find the most populous continent using hashmap and I don't know where to go from here.
These are my fields and I want to put the continent in the key section and population in the value section
private String name;
private int population;
private double area;
private String continent;
This is my attempt for creating that method but it's incomplete.
public void findMostPopulousContinent() {
/* Hashmap<Key, Value> */
HashMap<String, Integer> dummy = new HashMap<String, Integer>();
for (int i = 0; i < size; i++) {
if (dummy.containsKey(catalogue[i].getContinent())) {
Integer pop = dummy.get(catalogue[i].getContinent());
pop = pop + catalogue[i].getPopulation();
}
else {
dummy.put(catalogue[i].getContinent(), catalogue[i].getPopulation());
}
}
}
What I wanted to happen is to put my instances in the hashmap, and if my instances have the same continent then add their population and then compare that with others and then print the continent with the highest population like
North America, 100000000
You need to aggregate the population, which you can use Map's merge() method for.
But you don't need all that code:
Given:
record Country(String continent, Integer population) {}
Country[] catalog;
then:
Map<String, Integer> continentPopulations = Arrays.stream(catalog)
.collect(groupingBy(Country::continent, summingInt(Country::population)));
The secret sauce is using the groupingBy(classifier, downstream) collector:
groupingBy(Country::continent, summingInt(Country::population))
To get the most populous continent, you can skip the reference to the map and use a stream to find the max based on population for you:
String mostPopulousContinentName = Arrays.stream(catalog)
.collect(groupingBy(Country::continent, summingInt(Country::population)))
.entrySet().stream()
.max(Map.Entry.comparingByValue())
.get().getKey();

How can I put in each list the element that have the same id?

I want to put in each list the element that have the same id, and then bring all these lists into a single list, here is my table, as you can see on the picture "Image Result of SQL request" the id=1 is repeated so I want to have a Java list which contains just the elements that with the id = 1, and another Java list with the id=2......
Image Result of SQL request
Here is my incomplete code:
//Calculate Distance Traveled of a device in a specified 2 dates VERSION 2
public void getDistanceTraveled2(Date StartDate,Date EndDate) {
boolean exist=false;
allDeviceList = (ArrayList<Device>) deviceBean.getListalldevice();// Get list of all device
for(int i=0;i<allDeviceList.size();i++)
{
List<Eventdata> list = deviceBean.getLatAndLongDeviceId(); // get the id lat and long for each device
List<Eventdata> list2 = new ArrayList<Eventdata>();
while (list.size()!=0){
String idCourant = list.get(i).getDevice().getDeviceid(); // get the first id
String idNext = list.get(i+1).getDevice().getDeviceid(); // get the second id
if (idCourant == idNext)
{
//double distance = Point2D.distance(x1, y1, x2, y2);
double distance = Point2D.distance(list.get(i).getLatitude(),list.get(i).getLongitude(),list.get(i+1).getLatitude(),list.get(i+1).getLongitude());//Calculate distance
list2.add((Eventdata) Arrays.asList(idCourant, distance)); // store id and distance into a list
}
else {
exist=true;
break;
}
}
}
}
You can use Map with key as Integer and Value as List of ResultBean
Map<Integer, List<ResultBean>> map= new HashMap<Integer, List<ResultBean>>();
List<ResultBean> resultList = new ArrayList<ResultBean>();
// fetch data in rsultList by ID from table
map.put(1, new ArrayList<ResultBean>());
generating list of every id is just too much and a O(n) considerable action..
instead create a "GeoDevice" Class wit id, lat, long and implement comparable
so you can sort by id.
then when you get the sql answer create one list of GeoDevices sort it and then
use it to get all you need by browsing it by the ids in the objects...
We can encapsulate the location data in a class named "Location".
class Location{
private double latitude;
private double longitude;
public Location(double latitude, double longitude){
this.latitude = latitude;
this.longitude = longitude;
}
public String toString(){
return this.latitude+","+this.longitude;
}
}
Then we can store the data in a data-structure as follows:-
Map<Integer,List<Location>> locationData = new HashMap<>(); // Java 7 or above
Data visualized in the above data-structure

How to filter the list of objects by price of promotions

How do I filter say if I have list of products associated with metadatas like price, promotions etc.. how would I filter by price range of by promotions...
public class Products {
private String name;
private int weight;
private String promotion;
private String nutrition;
private int price;
//constructor ,, getter, setters
}
I will pass list of products to a arraylist and want to filter by price or promotion and it should display me only those come under that criteria..
If you're using Java8 you can use the Streams API to create a new list filtered from the existing list. Say you have an ArrayList of Products in a variable called list, and you only want the ones with price equal to 30, then it would look like this...
final List<Prouduct> filtered = list.stream()
.filter((elt) -> elt.getPrice() == 30)
.collect(Collectors.toList())
EDIT:
You will also have to change the access modifyers for your variables from private to public.
You will have to iterate over each object in the array and check if the values match with the filter
Example:
int filter=10;
for(int x=0;x<array.length;x++){
if(array[x].weight==filter){
System.out.println(array[x].name);
}
}
where array is an array of objects of the product class

A data structure similar to a HashMap with more than one "distinct" value

Is there any similar data structure that stores a key and unlike a HashMap<Key, Value> it stores more value regarded to a single key? If not, any suggestion for doing so? Because making several HashMap with same key and different values does not look so neat.
EDIT
When I said more than one value, I mean distinct value. For example, consider a map that has a key for each person and we wish to store persons Name and address and phone number.
Based on your edit you probably want to still store a single Value for each Key but make the value an Object. For example
public class PersonInfo {
private String name;
private String address;
private String phoneNumber;
etc...
}
and define your map as HashMap<Key, PersonInfo>
Check Guava's Multimap ! It let you have multiple values for the same key.
Example
Multimap<String, String> multimap = ArrayListMultimap.create();
multimap.put("Fruits", "Banana");
multimap.put("Fruits", "Apple");
multimap.put("Fruits", "Pear");
multimap.put("Vegetables", "Carrot");
// Getting values
Collection<string> fruits = myMultimap.get("Fruits");
Guava is a really useful library for java programmer you should definitely check it out !
Edit
Well after you edit you really just need a simple HashMap<Key, Person>. You can define your Person class like this:
public class Person {
private String name;
private String address;
private String phoneNumber;
public Person(String name, String address, String phoneNumber) {
this.name = name;
this.address = address;
this.phoneNumber = phoneNumber;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public String getPhoneNumber() {
return phoneNumber;
}
}
Use your HashMap<Key, Person> where Key could be a String for example:
Map<String, Person> personMap = new HashMap<String, Person>();
personMap.put("patrick_key", new Person("Patrick", "1000 Notre-Dame street", "123456789"));
personMap.put("stephan_key", new Person("Stephan", "2000 Notre-Dame street", "987654321"));
then you can access Patrick like that:
Person person = personMap.get("patrick_key");
Use a hashmap and each "value" is a list (linked or double linked on the basis of your needs).
A simple solution to this is to create some form of PersonInfo object, then map that value along with the key String. When you want to call the distinct key, you can just retrieve the object which contains any value you wish to describe about that person.
If you then want them to be distinct, you can record each phone number on a separate list and any time the user inputs a number, you can just check it against the global list of numbers.
(address/name's can be used twice because they're fairly common ie. think Junior and Senior living in the same home)

Sort by multiple columns, Java 8

Consider the following table:
Name Code Number
Mike x6 5.0
Mike b4 3.0
Mike y2 1.0
Tom y2 4.5
Tom x6 4.5
Tom b4 1.0
Susi x6 4.0
Susi y2 3.0
Susi b4 2.0
I have three columns, it should be sorted first of all by the column "Name" and then by the column "Number". I wanted to do this with Dictionary (use String array as value and Double as key) and then sort by value, but I miss the sort by the name.
Map<Double, String[]> map = new HashMap<Double, String[]>();
map.put(5.0, {"Mike", "x6"});
System.out.println(map.get(5.0));
I don't know what is the best way to store my data. I would like also to know the solution in Java 8.
First of all, you should make each line of your table an object:
public class MyData {
private String name;
private String code;
private Double number;
public MyData(String name, String code, Double number) {
this.name = name;
this.code = code;
this.number = number;
}
public String getName() {
return name;
}
public String getCode() {
return code;
}
public Double getNumber() {
return number;
}
}
Using Map<Double, String[]> does not represent what you are trying to achieve. A Map is used to create a link between an unique key an a value. Does it make sense for each number to be associated to a name and a code?
Once you have this object, it is much easier to sort it according to its properties:
List<MyData> list = new ArrayList<>();
list.add(new MyData("Mike", "x6", 5.0));
list.add(new MyData("Mike", "b4 ", 3.0));
list.add(new MyData("Mike", "y2", 1.0));
list.add(new MyData("Tom", "y2", 4.5));
List<MyData> sortedList = list.stream()
.sorted(Comparator.comparing(MyData::getName).thenComparing(MyData::getNumber))
.collect(Collectors.toList());
I think a Map is the wrong data structure for your case, as Maps explicitly DO NOT DEFINE an order based on the values.
But you may help yourself with streams. Something like:
map.entrySet().stream().sorted((e1, e2) -> e1.getValue()[0].compareTo(e2.getValue()[0])).map(e -> e.getKey()).toArray(l -> new Integer[l])
this will give you an array of keys, sorted by the first integer in the value array. the full value you may then look up in the original map.

Categories

Resources