Returning ArrayList from HashMap - java

I have a program that adds the name of the donors as key in the HashMap with their Cities(ArrayList of city) as value. So, I have to take the name of the donor and first check whether this name is available in the map or not , if the name is available and the donor is donating from a different city then I need to update the cities arraylist in the map and if it is a new donor then I need to just add the donor in the map.
if anyone can help me with this problem, I have been facing great crisis because of this. Totally stucked.
I have attached my code.
import java.util.Scanner;
import java.util.ArrayList;
import java.util.HashMap;
public class MultCityMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
CollectionUtil cu = new CollectionUtil();
String donorName,city;
Scanner sc = new Scanner(System.in);
ArrayList<String> donorCity = new ArrayList<String>();
boolean choiceFlag = true;
while(choiceFlag){
System.out.println("Enter name");
donorName = sc.nextLine();
System.out.println("Enter city name");
city = sc.nextLine();
ArrayList<String> newCity = cu.nameKeyChecker(donorName,donorCity);
newCity.add(city);
cu.addDonor(donorName, newCity);
System.out.println("donate again? (1/0)");
int choice = sc.nextInt(); sc.nextLine();
if(choice == 1)
choiceFlag = true;
else
choiceFlag = false;
}
System.out.println(CollectionUtil.donorMap);
}
}
import java.util.ArrayList;
import java.util.HashMap;
public class CollectionUtil {
static HashMap<String, ArrayList<String>> donorMap = new HashMap<>();
public ArrayList<String> nameKeyChecker(String name, ArrayList<String> city){
if(donorMap.containsKey(name))
return (ArrayList<String>)donorMap.get(name);
else
donorMap.put(name, city);
return (ArrayList<String>)donorMap.get(name);
}
public void addDonor(String name, ArrayList<String> city){
donorMap.put(name, city);
}
}

You've made this way more complicated than it needs to be.
Given: Map<String, List<String>> donors; representing a donor's name with a list of cities donated to, all you need to add a new city is:
donors.computeIfAbsent(donorName, d -> new ArrayList<String>()).add(newCity);
This code will fetch the existing list, but, if there is no list, it 'computes' a value first (by making a new list). Then, that list is returned (be it the newly computed list, or the existing one); so you just add the new city to it.
Voila. you can get rid of half of your code now; you don't need the util class (in general, if you name a class 'util', rethink things), nameKeyChecker is not needed, you don't need the donorCity variable here either.

Definitely the code is much more complicated than it has to be. Perhaps, you need little more practice on programming.
However, if you want to fix you code all you need is addDonor method that looks something like following
public void addDonor(String name, String city) {
if (donorMap.containsKey(name)) {
donorMap.get(name).add(city);
} else {
ArrayList<String> newCity = new ArrayList<>();
newCity.add(city);
donorMap.put(name, newCity);
}
}
You can get rid of nameKeyChecker.

Related

Searching a multi-dimensional array in a menu page

I'm trying to create a menu page that allows addition to the array, output of the array and to search by name. I'm struggling with the search part, as it is a multi-dimensional array. How do I search just the names part of each object?
I'm also not sure how to loop this so that they return to the main page after each request, and therefore the array remains updated with any new editions.
package qa.com.task;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import qa.com.task.Person;
public class Runner {
public static void main(String[] args) {
Person pp1 = new Person("Karen", 27, "DevOps Engineer");
Person pp2 = new Person("Jim", 24, "Software Engineer");
// Create array
ArrayList<Person> people = new ArrayList<Person>();
people.add(pp1);
people.add(pp2);
// Search array
Scanner scan = new Scanner(System.in);
System.out.println("---------------------MENU---------------------");
System.out.println("------Create--------Search-------Output All---");
System.out.println("------type c--------type s---------type o-----");
String request = scan.nextLine();
if (request.contains("c")){
//CREATE NEW PERSON
System.out.println("----------Create Request: Enter Name----------");
String newname = scan.nextLine();
System.out.println("-------------------Enter Age-------------------");
Integer newage = scan.nextInt();
scan.nextLine();
System.out.println("-------------------Job Title-------------------");
String newjobtitle = scan.nextLine();
Person ppnew = new Person(newname, newage, newjobtitle);
people.add(ppnew);
System.out.println("-----Updated Array with New Creation Request----");
System.out.println(Arrays.toString(people.toArray()));
}
if (request.contains("s")){
//SEARCH
System.out.println("----------Search Request: Enter Name----------");
String searchname = scan.nextLine();
}
if (request.contains("o")){
//OUTPUT DATABASE
System.out.println("----------------Output Request:----------------");
System.out.println(Arrays.toString(people.toArray()));
}
}}
You can filter your people list based on a person name.
List<Person> filteredPeople = people.stream()
.filter(person -> person.getName().contains(searchname)) // Filter condition
.collect(Collectors.toList()); // Get the result as list
Then you can do what you want with filteredPeople.
Otherwise you can use a traditional for loop to iterate over the list and "print" Persons who match the condition, something like below.
List<Person> people...;
boolean stop = false;
while(!stop) {
// print menu (with exit command)
// handle commands and if exit command, set stop = true.
}

If matched then add elements of ArrayList_A to ArrayList , if not then add elements of ArrayList_B to ArrayList

I have the following code:
package sportsCardsTracker;
import java.io.*;
import java.text.*;
import java.util.*;
import java.util.stream.Collectors;
public class Test_Mark6 {
public static ArrayList<String> listingNameList;
public static ArrayList<String> finalNamesList;
public static void main(String[] args) throws IOException, ParseException {
listingNameList = new ArrayList();
listingNameList.add("LeBron James 2017-18 Hoops Card");
listingNameList.add("Stephen Curry Auto Patch, HOT INVESTMENTS!");
listingNameList.add("Michael Jordan 1998 Jersey Worn Card");
ArrayList<String> playersNamesList = new ArrayList();
playersNamesList.add("LeBron James");
playersNamesList.add("Stephen Curry");
playersNamesList.add("Michael Jordan");
finalNamesList = new ArrayList();
String directory = System.getProperty("user.dir");
File file = new File(directory + "/src/sportsCardsTracker/CardPrices.csv");
FileWriter fw = new FileWriter(file, false); //true to not over ride
for (int i = 0; i < listingNameList.size(); i++) {
for (String listingNames : listingNameList) {
List<String> result = NBARostersScraper_Mark3.getNBARoster().stream().map(String::toLowerCase).collect(Collectors.toList());
boolean valueContained = result.stream().anyMatch(s -> listingNames.toLowerCase().matches(".*" + s + ".*"));
if(valueContained == true) {
finalNamesList.add(//The players' name);
}
}
fw.write(String.format("%s, %s\n", finalNamesList.get(i)));
}
}
}
Basically, in the listingsNameList, I have the listing's names and in the playersNamesList, I have all the players' names. What I would like is that, if the code matches the names between the two arrayList and find a player's name, it should returns the players' only.
For example, instead of "LeBron James 2017-18 Hoops Card" it should return "Lebron James" only. If it does not find anything, then just return the listing's name. So far, I have created a new ArrayList namely finalNamesList, my idea would be using an if statement (if match found then add players' name to finalNamesList, if not add the listing' name to finalNamesList). However the code above is not working and it is just adding all of the names in the listingNameList to the finalNamesList. I suspect that the way I grab the index is wrong - but I don't know how to fix it.
The method you are using to match a pattern that seems wrong. Instead of "match()" you can use string contains method as below.
List<String> temp = new ArrayList<>();
for (String listingNames : listingNameList) {
temp = playersNamesList.parallelStream().filter(s -> listingNames.toLowerCase().contains(s.toLowerCase())).map(s -> s).collect(Collectors.toList());
if(temp.size() > 0){
System.out.println(temp.get(0));
//fw.write(String.format("%s, %s\n", temp.get(0));
}
}
One more thing, You don't need to use 2 for loop here, with one loop you can achieve your output.
Though You can still optimize this code, I have taken the temp list above that you can avoid.

Is it possible to compare a string to the name of an array in a 2D array?

I am trying to find an array in a two dimensional array using a string input from the user. But, I keep getting the "String[][] cannot be converted to to String" error. Can I do this with a keyboard scanner and strings or is there a more logical solution to this problem.
import java.util.Scanner;
public class QandA{
public static void main(String[] args){
String entry;
String[] Why = new String[]{"Because.", "Just Because.", "Why yourself."};
String[][] Questions = new String[][] { Why };
Scanner k = new Scanner(System.in);
entry = k.next();
for (int i=0 ; i < Questions.length ; i++){
if (entry.equalsIgnoreCase(Questions)){
System.out.println("Test");
break;
}
if (i == Questions.length){
if (!entry.equalsIgnoreCase(Questions)){
System.out.println("Test2");
}
}
}
}
}
EDIT:
I have changed my 2D array into a hashmap but am getting a "cannot find symbol, class Hashmap" even after importing java.util.HashMap; Help? [FIXED]
import java.util.Scanner;
import java.util.Map;
import java.util.HashMap;
import java.util.*;
public class QandA{
public static void main(String[] args){
String UE;
String[] Why = new String[]{"Because.", "Just Because.", "Why yourself."};
Map<String, String[]> Questions = new HashMap<>();
Questions.put("Why", Why);
Scanner k = new Scanner(System.in);
UE = k.next();
if(Questions.keySet().stream().filter(UE::equalsIgnoreCase).findFirst().isPresent()) {
System.out.println("Test");
} else {
System.out.println("Test2");
}
}
}
First you need to use a Map (instead of a String[][]) to map the name of the array variable to its instance:
String[] Why = new String[]{"Because.", "Just Because.", "Why yourself."};
Map<String, String[]> Questions = new HashMap<>();
Questions.put("Why", Why);
Next, you can perform the Test / Test2 check in many ways. Here is one way:
if(Questions.keySet().stream().filter(entry::equalsIgnoreCase).findAny().isPresent()) {
System.out.println("Test");
} else {
System.out.println("Test2");
}
As a side note, your variable names are very misleading. "Entry" has a different meaning in the context of maps, since it encapsulates a Key+Value Pair. You should use meaningful variable names and conform to existing Java conventions regarding case, etc.

Searching through Arraylist In Java for particular pattern

Consider I have an Arraylist which holds products name like
Dell Inspiron Laptop
Apple iPad
Samsung S4
I want to have a search like if one searches for S4, it returns Samsung S4. I tried to find the answer in many websites but didn't get one. I used .matches and .contains but was of no use.
Iterate the product names list, assume the variable for product name is name, which is a String type.
You can use if (name.contains(value)) { or if(name.indexOf(value)!=-1){ to check whether the name contains the value to be searched.
Have a try with the following code:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<String> prodNames = new ArrayList<String>();
prodNames.add("Dell Inspiron Laptop");
prodNames.add("Apple iPad");
prodNames.add("Samsung S4");
// Search S4 and it will print Samsung S4 in Console
System.out.println(search("S4", prodNames));
}
public static String search(String value, List<String> prodNames) {
for (String name : prodNames) {
if (name.contains(value)) {
return name;
}
}
return null;
}
}
You can write an utility function like below, that scans through contents of list for particular pattern. Hope this works for your.
public static void findMatch(List<String> listNames, String searchTerm){
for(String inName:listNames){
if(inName!=null)
if(inName.contains(searchTerm))
System.out.println(" Match Found for "+inName);
}
}
You could do something like:
public List<String> matches (List<String> dataList, String matchStr){
List<String> result = new ArrayList<String>();
if (matchStr != null) {
matchStr = matchStr.toLowerCase();
for(String d : dataList){
if (d.toLowerCase().contains(matchStr)) {
result.add(d);
}
}
}
return result;
}
First of all clean up the definition of the Array. I'm guessing that it actually looks like this:
{ "Dell Inspiron", "Apple iPad", "Samsung S4" }
Then go run this in your IDE :
import java.util.ArrayList;
import java.util.List;
class TestSearching {
public static void main(String args[]) {
List<String> products = new ArrayList<String>();
products.add("Dell Inspiron");
products.add("Apple iPad");
products.add("Samsung S4");
System.out.println("Matches to S4 : " + findMatches(products,"S4"));
}
public static List<String> findMatches(List<String> products, String searchTerm) {
List<String> result = new ArrayList<String>();
for (String product : products) {
if ( product.contains(searchTerm) ) result.add(product);
}
return result;
}
}
If you always want to do a lookup on the string after the first space, then maybe you don't want to use an ArrayList
Maybe you should use a Map<String, String> of product, full name e.g. "S4", "Samsung S4"
Then lookups will be much faster.

Android: Find a value inside an Array with a "a like" value

I'm having problem with this part
My Code:
String[] sample = {'name=NAME', 'add=ADD', 'age=AGE', 'gender=GENDER'};
for(int a = 0; a < sample.length; a++) {
if(Arrays.asList(sample).contains("name")) {
Log.d(tag, "successful");
} else {
Log.d(tag, "failed");
}
}
When I'm using this code, it doesn't return true, but when I use .contains("name=NAME")
it returns true.
Is there any possibility to compare a string value using not too specific string?
BTW, those string values came from a file.txt.
If you use Arrays.asList(sample) you will have a list containing the String "name=NAME" hence it doesn't contain the String "name"
You should loop over the array (not needed to create the list)
boolean found = false;
for (String s: sample)
if (s.contains("name"))
found=true;
To get a value based on key:
1) You can use HashMap object
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main(String args[]) {
// create hash map
HashMap newmap = new HashMap();
// populate hash map
newmap.put("name", "abcde");
newmap.put("age", "XX");
newmap.put("Gender", "Male");
// get value of key Gender
String val=(String)newmap.get("Gender");
// check the value
System.out.println("Value for key 3 is: " + val);
}
}
2) You can also use Map object
Map<String, String> map = new HashMap<String, String>();
map.put("name", "abcde");
map.put("age", "XX");
String val=(String)map.get("name");
3) You can also use two dimentional array of string
String data = "name=Name,age=Age";
String[] rows = data.split(",");
String[][] matrix = new String[rows.length][];
int r = 0;
for (String row : rows) {
matrix[r++] = row.split("\\=");
}
System.out.println(matrix[1][1]);
.contains method will check whether the object is present in the ArrayList or not.
Here in your case objects are : "name=NAME","add=ADD","age=AGE", "gender=GENDER" which are of String type. So it is obvious that it returns false.
For you, better practice is to create a class named Person which has attributes like name,add,age and gender. Then store the object of it in ArrayList and you can check whether object is in ArrayList of not using .contains() function. Like below :
class Person{
String name;
String add;
int age;
String gen;
// All getters and setters methods will be here.
}
public static void main(String[] args){
Person p = new Person();
//Here you can set the properties of person using p.setXXX() methods
//Now suppose you have ArrayList of Person object named "per" then you can check
// whether Person exist in it or not using contains like below
per.contains(p) //returns true if per contains object p
//or you can check name by below code
for(Person temp:per){
if(temp.getName().equals(name)){ //returns true if name matchs with Persons name
//do something
}
}

Categories