I have a list of objects having code and user name. I can get the code and username with getCode() and getUserName(). I can think of using MultiMap if I must display only code and list of usernames associated for each code. But how to display all three details (code, usercount, usernames) with different data types using Java?
Code - String (Key)
UserCount - Integer (Value)
UserNames - List (Value)
How to display in the below format using Java?
Code UserCount UserNames
Abc 2 Jack, Mary
Def 1 Steven
Ghi 3 James, Ray, Jim
If I understand, you have a List<YourObject> where YourObject is the class :
public class YourObject {
public String code;
public String userName;
// getters and constructor(s)
}
When you say :
I must display only code and list of usernames associated for each code
It means that in your List<YourObject>, if two objects A and B have the same code value X, you want to display something like "Code X ; usernames = [A.getUserName(), B.getUserName()]" ?
But you also want to add a userCount attribute which is the size of the usernames list (in my above exemple : 2).
I think you can create a utility method that takes your List<YourObject> as parameter and return a Map<String,List<String>> where the key string is the code and the List of strings is the usernames.
Something like : (Sorry for the stream version, I was too lazy to write more lines) :
public static Map<String,List<String>> process(List<YourObject> list) {
return list.stream().collect(Collectors.toMap(YourObject::getCode, x -> list.stream().filter(e -> x.getCode().equals(e.getCode())).map(YourObject::getUserName).collect(Collectors.toList()), (x,y) -> x));
}
The display you wanted :
process(yourList).forEach((k,v) -> {
System.out.println("Code : " + k + " | userCount :" + v.size() + " | Usernames =" + v)
});
Related
I'm trying to find a nice solution to a movie filtering system built in java and with a mysql database. The user is supposed to be able to filter which movies they wish to see based on a number of attributes, such as: director, actor, length, genre, year,...,. In total there are 11 fields which can be used to filter the query.
The problem is some of these fields can (and probably will) be left blank. For instance, maybe the user only wants to filter data based on a certain genre, director and length. Or maybe they only want to filter it based on the prodution studio, and dont care about the other filter options.
I have made a connection to the server, and the problem is in creating the "SQL_String" that I will use in statement.executeQuery(SQL_String).
Lets say I only wanted to filter for one field. Then I know I could write
String field = //user input (for example: actor)
String filter = //user input (for example: 'tom cruise')
String SQL_String = "SELECT * FROM Movies WHERE "+field + "=" +filter
But if i want to allow the user to filter based on several (or zero) fields, then I dont know how to write the code.
Some example queries could be:
"SELECT * FROM Movies WHERE (director = 'steven spielberg' AND genre = 'action' AND length >100)"
"SELECT * FROM Movies WHERE (type = 'tv-series' AND actor = 'bob odenkirk')"
So the user can specify which fields they want to filter (if any) and i need to come up with a java code that can take those into account and construct a query string.
Since you don't know how many fields the user will filter on but you do know that the data you're dealing with has two parts (the field and the filter), the first two things that come to my mind are maps and tuples. Since, unlike Python, Java does not have a built in tuple data type (to my knowledge), here is a small example solution that I thought of for your problem solved using Java's HashMap and Map classes.
In this example, I create a HashMap with the key being a string for the "field" and the value being a string for the "filter". You can set these values based on the user input wherever you have that in your code (in this example, simply hard-coded in the main method). Then you can loop through the key-value pairs in your HashMap (see this helpful post), appending the key and value as well as the additional characters necessary for the query. This is a simple example but shows a possible solution route.
If you want to make sure that this solution works for the cases where you filter value is an integer, then just add in another if-statement in the loop to try parsing for an integer and if one exists to not add the extra \' escape characters.
import java.util.HashMap;
import java.util.Map;
public class MovieQueryTest {
public static void main(String[] args) {
String SQL_Query = "SELECT * FROM Movies WHERE ";
HashMap<String, String> queryFilters = new HashMap<>();
queryFilters.put("director", "Steven Spielberg");
queryFilters.put("type", "tv-series");
queryFilters.put("actor", "Bob Odenkirk");
boolean firstQueryFilter = true;
for (Map.Entry<String, String> entry : queryFilters.entrySet()) {
if (firstQueryFilter) {
SQL_Query += entry.getKey() + "=\'" + entry.getValue() + "\'";
firstQueryFilter = false;
} else {
SQL_Query += " AND " + entry.getKey() + "=\'" + entry.getValue() + "\'";
}
}
System.out.println(SQL_Query);
}
}
Enviroment: Java 7
I have a hashmap 'pdf' of Aircrew details that has the following key structure:
public static Map<String, String> pdf;
PilotName JONES
PilotFirstname Jim
PilotID 12345
PilotLicense AAD987
PilotDOB 12/12/2001
PilotGender Male
PilotEthnicity
PilotAddress 123 Any Street
CopilotName SMITH
CopilotFirstname Thomas
CopilotID 987654
CopilotLicense AAB9475
CopilotAddress 456 Any Street
CopilotDOB 12/03/1987
CopilotGender Male
CopilotEthnicity European
CabinManagerSurname
CabinManagerFirstName BROWN
CabinManagerID 48573
CabinManagerDOB
CabinManagerGender
CabinManagerEthnicity
CabinManagerAddress
Hostess1Surname
Hostess1FirstName
HostessID
Hostess1DOB
Hostess1Gender
Hostess1Ethnicity
Hostess1Address 789 Any Street
Hostess2Surname EDWARDS
Hostess2FirstName Mary
HostessID 475804
Hostess2DOB 11/10/1990
Hostess2Gender Female
Hostess2Ethnicity European
Hostess2Address
Hostess3Surname
Hostess3FirstName
Hostess3ID 489282
Hostess3DOB
Hostess3Gender
Hostess3Ethnicity
Hostess3Address
NB: The field names for crew and pilots are different (Surname/Name Firstname/FirstName).
I want to test if any of certain fields are not empty then call createPerson() method.
The fields to be tested differ for Cabin Crew from Pilots.
I made this attempt but the code is ugly:
List<String> pilotRoles = ["Pilot", "Copilot"];
List<String> cabinRoles = ["CabinManager", "Hostess1", "Hostess2", "Hostess3"];
for (String role : pilotRoles) {
if ( String.isNotNullOrEmpty(pdf.get(pilotRole +"Name")) || String.isNotNullOrEmpty(pdf.get(pilotRole +"Firstname")) || String.isNotNullOrEmpty(pdf.get(pilotRole +"ID")) || String.isNotNullOrEmpty(pdf.get(pilotRole +"License"))) {
listPeople.add(createPerson(pdf, pilotRole));
for (String role : cabinRoles) {
if ( String.isNotNullOrEmpty(pdf.get(cabinRole +"Surname")) || String.isNotNullOrEmpty(pdf.get(cabinRole +"FirstName")) || String.isNotNullOrEmpty(pdf.get(cabinRole +"ID")) ) {
listPeople.add(createPerson(pdf, cabinRole));
For the above data the createPerson routine would be entered for both pilots as at least 1 of the tested fields is not null or empty.
The createPerson routine would NOT be entered for hostess1 and all of the tested fields are null or empty.
Is there a more elegant way? If so how.
I'd try something like this: In addition to your lists of roles, create an additional list that holds the names of all attributes, like "Name" etc.
Then you can then create a function to filter your roles for fields that are missing in your pdf map, like this:
private List<String> getRolesOfMissingUsers(Map<String, String> pdf, List<String> roles, List<String> attributes) {
return roles.stream().filter(role -> attributes.stream().map(attribute -> role + attribute)
.anyMatch(roleAttribute -> StringUtils.isNotBlank(pdf.get(roleAttribute))))
.collect(toList());
}
You can then use the result of this method to create your missing users. Here is an example just for your pilot rules:
for (String role : getRolesOfMissingUsers(pdf, pilotRoles, Arrays.asList("Name", "Firstname", "ID", "License"))) {
listPeople.add(createPerson(pdf, role));
}
EDIT: I noticed you're on Java 7, so you could try this instead:
for (String role : pilotRoles) {
for (String attribute : Arrays.asList("Name", "Firstname", "ID", "License")) {
if (StringUtils.isNotBlank(pdf.get(role + attribute))) {
listPeople.add(createPerson(pdf, role));
break;
}
}
}
If you extract this to a method and pass the list of attributes as a parameter, you should also be able to use this for your crew and pilot list.
Dynamic Columns from a Hashmap property in DynamicJasper. Is it possible?
Hi,I'm really new to Dynamic Jasper. I'm having some trouble with some columns that should come from a property of Hashmap. I'll put a example to be clearer:
class Product {
private String name;
private String price;
private String whatever;
private Hashmap<String,String> comments;
}
My DataSource is a List<Product> of products;
|__name___|___price___|_____whatever_____|______First item inside the comments list_____|___Second item inside the comments list____|___N item inside the comments list __|
the name of the columns will be the same as key in the hashmap.and value is the value of the hashmap.
every object(product) has a hashmap with different comments(values) but same keys.for example:
product1: name1,price1, hashmap: ("quality","good")("easyToUse","yes")
product2: name2,price2, hashmap: ("quality","bad")("easyToUse","no")
and the report should be like this:
|__ name_______|______price _____|_____quality_____|______easyToUse______|
|___name1_____|______price1_____|______ good_____|______ yes___________|
|___name2_____|______price2_____|______ bad______|______ no____________|
Is it possible or should I try another approach?
how can I create columns dynamically?and set them correct value?
Best Regards
What you can do is iterate over every key inside the products, for each one print the name of the product, its price, the key and the corresponding value.
for(Product p : Products){
for(String key : p.comments.keySet()){
System.out.println(p.name +", " + p.price", "+ key +" " + p.comments.get(key));
}
}
I have the following problem in Java.
I have this eunm that contains 2 values that represent 2 String values "COORDINATION" and "PISC" :
private enum exclusion {COORDINATION, PISC};
So I have create this getEnums() method that return an HashSet containing the values of the enum as a String:
private static HashSet<String> getEnums() {
HashSet<String> values = new HashSet<String>();
for (Exclusion e : Exclusion.values()) {
//values.add(Exclusion.values());
values.add(Exclusion.values().toString());
System.out.println("Inserted values: " + e.values().toString());
}
return values;
}
The problem is that when this method is called the returned values object contains 2 String as I espect but using the deubugget the values putted into this HashSet are not "COORDINATION" and "PISC" but something like this:
Inserted values: [Legp.prc.km.actions.configurationProject.ConfigurationProjectAction$Exclusion;#34653605
Valore inserito: [Legp.prc.km.actions.configurationProject.ConfigurationProjectAction$Exclusion;#39510a30
I think that the problem is related about how I insert the values into the values HashSet
Then, elsewhere into my code, I have the following cycle:
HashSet esclusionHashSet = getEnums();
for (DLFolder dlFolder : listFolder) {
if (dlFolder.getPath().split("/").length <= 4 && dlFolder.getPath().contains(KmConstants.TAXONOMY_PARENT_FOLDER) && !esclusionHashSet.contains(dlFolder.getName())) {
treePath.put(dlFolder.getPath(), dlFolder);
path.add(dlFolder.getPath());
}
}
As you can see in this for all element into an object of my list I check if the name of the dlFolder object (that could be "COORDINATION" or "PISC" is not into the esclusionHashSet that contains the values inside my original exclusion enum, the check is done by:
!esclusionHashSet.contains(dlFolder.getName())
The problem is that it returns alwaysl FALSE (it seems that the esclusionHashSet* does not contain the **"COORDINATION" and "PISC" values)
How can I fix this issue? What am I missing?
Instead of:
for (Exclusion e : Exclusion.values()) {
//values.add(Exclusion.values());
values.add(Exclusion.values().toString());
System.out.println("Inserted values: " + e.values().toString());
}
You should do:
for (Exclusion e : Exclusion.values()) {
values.add(e.name());
System.out.println("Inserted value: " + e.name());
}
What you are currently adding is the String representation of the array containing all the values of your enum, not the String representation of every value.
My specific problem is related to an Android project but this is not a specific android question.
I am basically just trying to come up with a way I can query a database and return results not based on exact matches but based on similar terms even outside the scope of a search on whether a String "contains" the typed value.
So for example, lets say I have a entry called "Popeye's Catfish". And lets say somebody enters the term "P's CatSalmon" and are looking for that entry. I would like to return a query list that shows essentially a "most similar" match.
I admit I am a complete novice at database queries so there might be ready answers out there that I just can't find (I did look). There are a few ways I can think to do this:
I could break apart the search string and look for separate parts of each string in a "contains" search of the actual entry. For example I could break out "P" "Cat" and "Salmon" search all three and do some other code to find out what the best result is. However, I'm really not sure how I would code it so that the program could pick the best segments. How would it know to pick out "cat" for example without just iterating through every possibility (which is almost certainly not realistic)?
I could just let the users suffer for a while until tags exist. What I mean is, once the correct entry is found by the "proper" name, I could just let users tag it with associated names and then include that separate associated name in the search by later users.
I can't come up with anything better than that based on my current level of knowledge.
Thanks in advance for the help.
I'm guessing that this is some sort of find location app. So let's assume that the number of locations is small, say less than 200.
You would start by building a search that looks for the "words" that the user typed in the locations. In your example, we have "P's" and "CatSalmon". "CatSalmon won't match anything, and neither will "P's".
So you return something that looks like this:
Locations found for "P's CatSalmon"
-----------------------------------
No locations found. Try using different search terms.
So, our user types "P CatSalmon".
So you return all the locations that start with the letter P, then the locations that contain the letter P.
Something like this:
Locations found for "P CatSalmon"
---------------------------------
Popeye's Catfish
Public library
Hope Restaurant
...
Now, here's where it gets interesting.
When the user picks a location, you log the search term and the location selected.
In your example, the user would pick "Popeye's Catfish".
So later, you manually add this key value to a synonym map.
Key Value
--------- ----------
CatSalmon Catfish
Over time, your searches will get better because your users will define the synonyms.
So, to recap.
You search for locations that start with a word.
You search for locations that contain a word.
You look in the synonym map for synonyms, and you repeat the start / contain process with the synonym(s).
Start locations are displayed first, then contain locations.
Finally, you do all this work on the server with the database. You pass the sorted location list to the phone. Don't make the phone do all the work.
This is something I put together essentially highlighting the closest matched term with a query based on the number of sequential characters
public class SequenceMatches {
public static void main(String [] args)
{
HashMap<String, Integer> map = new HashMap<String, Integer>();
String query = "P's SalmonCat ";
map = addTermsToHashMap(map);// add terms to a hash map
map = compareFirstCharacter(map, query);// compare the initial first character
map= compareSequentialCharacters(map, query);// compare terms to query and add score based on the number of matches
printResults(map);
}
public static HashMap<String,Integer> addTermsToHashMap(HashMap<String,Integer> map){
String term = "Popeye's CatFish";
String otherTerm = "Popets CatSalmon";
map.put(term,0);
map.put(otherTerm,0);
return map;
}
public static HashMap<String,Integer> compareFirstCharacter(HashMap<String,Integer> map,String query){
for(Map.Entry<String,Integer> e: map.entrySet())
{
String term = e.getKey();
char [] termChar = term.toCharArray();
char [] queryChar = query.toCharArray();
if((queryChar[0]) == (termChar[0]))
{
int value = map.get(term);
map.put(term,++value);
}
}
return map;
}
public static HashMap<String,Integer> compareSequentialCharacters(HashMap<String,Integer> map,String query){
for(Map.Entry<String,Integer> e: map.entrySet())
{
String term = e.getKey();
char [] termChar = term.toCharArray();
char [] queryChar = query.toCharArray();
for(int i = 0; i < queryChar.length -1; i++)
{
for(int j = 0; j < termChar.length -1; j++)
{
if(queryChar[i] == termChar[j] )
{
if((queryChar[i + 1]) == (termChar[j + 1]))
{
System.out.println((queryChar[i + 1]) + " " + (termChar[j + 1]));
int value = map.get(term);
map.put(term,++value);
break;
}
}
}
}
}
return map;
}
public static void printResults(HashMap<String,Integer> map)
{
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey()+" : "+entry.getValue());
}
}
}