i have cleanse method which is cleaning data while i am giving input from eclipse console, while entering i have putted some field as null, i am storing the cleanse data in map and calling that data in 2 different method for searching but it is calling everytime one method only
public void cleanse(SiperianClient oSiperianClient) {
Scanner sc = new Scanner(System.in);
Field accountfield = new Field();
accountfield.setName("Acct_Name");
writeStringLog("Enter Account Name:");
accountfield.setValue(sc.nextLine()); // "Arthritis Group"
record.setField(accountfield);
/// ...so on ..
Map<String, Object> cleanseMap = new HashMap<>();
while (iterator.hasNext()) {
Record rec = iterator.next();
// Collection<Field> fields = rec.getFields();
cleanseMap.put("CUST_NM", rec.getField("CUST_NM").getValue());
cleanseMap.put("ADDR_LN1", rec.getField("ADDR_LN1").getValue());
cleanseMap.put("ADDR_LN2", rec.getField("NPI_ID").getValue());
}
if (cleanseMap.get("NPI_ID").equals(NPI_ID)) {
this.SearchMatch(cleanseMap, oSiperianClient);
} else {
this.searchQueryMatch(oSiperianClient);
}
}
here NPI ID is null as i have not inserted any value from console
Related
My code below
import java.util.*;
import java.io.*;
public class main {
public int finalcost;
public static void main(String[] args) throws FileNotFoundException, IOException {
Scanner input = new Scanner(System.in);
int totalAdd = 0;
boolean done = false;
// to store specific properties ex item size and price
HashMap<String, String> specificPropsMap = new HashMap<String, String>();
// stores an array list of all the sizes and price
ArrayList<HashMap<String, String>> propsList = new ArrayList<HashMap<String, String>>();
// the item list stores the name of the item as the KEY and item size and price
// as data
HashMap<String, ArrayList<HashMap<String, String>>> itemsMap = new HashMap<String, ArrayList<HashMap<String, String>>>();
// this stores the service name than the cost.this is the one we will be adding
// too after getting the data;
HashMap<String, Integer> cartMap = new HashMap<String, Integer>();
BufferedReader br = new BufferedReader(new FileReader("PA2.txt"));
String line = br.readLine();
while ((line = br.readLine()) != null) {
// stores the data base on commas
String[] fields = line.split(",");
String serviceName = fields[0];
String fileName = fields[1];
String cost = fields[2];
if (specificPropsMap.containsKey(serviceName)) {
// do nothing
} else {
specificPropsMap.put(serviceName, null);
}
// gets the file name from the first reader
BufferedReader brCVS = new BufferedReader(new FileReader(fileName));
String lineCVS = brCVS.readLine();
while ((lineCVS = brCVS.readLine()) != null) {
String[] cvsFields = lineCVS.split(",");
String brandName = cvsFields[0];
String nameItem = cvsFields[1];
String itemSize = cvsFields[2];
String itemPrice = cvsFields[3];
// check if itemname is in specificPropsMap
if (specificPropsMap.containsKey(cvsFields[1])) {
// do nothing
} else {
specificPropsMap.put(itemSize, nameItem);
}
propsList.add(specificPropsMap);
if (itemsMap.containsKey(nameItem)) {
// do nothing
} else {
itemsMap.put(nameItem, null);
}
} // end inner while loop
int stringCosttoInt = Integer.parseInt(cost.trim());
if (cartMap.containsKey(serviceName)) {
// do nothing
} else {
cartMap.put(serviceName, stringCosttoInt);
}
} // end outer while loop
System.out.println("Welcome to Assisgnment two app");
while (done == false) {
System.out.println("Enter the item you are looking for or enter done check out: ");
String key = input.nextLine(); // use key to find if item is in the itemsMap;
if (key == "done") {
done = true;
} else {
if (itemsMap.containsKey(key)) {
System.out.println("Enter the Size you want :");
// now check for the item name, than size, if not return item not there;
int sizeKey = input.nextInt(); // use key to find item in the area
if (itemsMap.containsValue(specificPropsMap.containsKey(sizeKey))) {
System.out.println("How many of " + key + " do you want:");
int numOfProduct = input.nextInt();
// add it to the cart;
} else {
System.out.println("No: " + sizeKey + " in the system");
}
} else {
System.out.println("No item by the name of: " + key + " in the system");
}
}
}
br.close();
input.close();
}
}
Question: How do I set the user input to search the item class to return the lowest total cost. The user enters item name, size and the amount. I know in storing the name in item, but I don't know how to match it with user input or how to get that data if that makes sense.2nd in also little confused when I read the file and i'm storing it as a String, I don't know how to make it into an int so I can do math with it..
Just to give you some help with the approach, I won't be going into detail about parsing, I think you got that covered.
Look at it from another perspective, from the input. What is the flow of the program?
User enters required item and size
Look if item is present
User enters quantity
Add to cart
Repeat
When 'done', check which Service offers lowest total price
Note: Assuming an item present in one Brand is present in all
So let's devise a Data Structure that can support this:
We need to maintain a Cart for each Service. In the end, we can cycle through each cart and return the lowest.
Maintain a Map<String, Integer> where String is the Service, and Integer is the total price
Whenever an Item is added by the user, add the price of that Item to each respective Service
Eg. If Lays is added, add price of Lays in Prime to total price of Prime, price of Lays in InstaCart to total price of InstaCart, etc
First thing you need to look up is if the Item is present; we can store it in a Map, say itemsMap.
What specific properties does each item have? There's service, brand, size, price. We can store it in another Map, say specificPropsMap.
Each Item can have multiple specific properties. i.e., There can be different combination of size, service, etc. for the same Item. So each Item needs to store multiple specific properties, which can be a List, say propsList.
To understand the above:
//Starting from the bottom-up
//To store specific properties
//Contains key-value pairs like: service = Amazon, brand = Nestle, size = 10g, price = 2
HashMap<String, String> specificPropsMap; //Has one set of specific props
//Consider an Item; it can have multiple specific properties, which we'll store as a List
//Eg: For Item = 'dark chocolate'
//specificProps1: service = Amazon, brand = Nestle, size = 10, price = 2
//specificProps1: service = InstaCart, brand = Cadbury, size = 10, price = 3
//Required: List<specificPropsMap>
ArrayList<HashMap<String, String>> propsList; //Has a list of specificPropsMaps for one item
//Now we need to store all Items; it can be a Map
//Required: Map<ItemName, propsList for that Item>
HashMap<String, ArrayList<HashMap<String, String>>> itemsMap;
//Initialize cart Map while parsing services
HashMap<String, Integer> cartMap; //Has initial values "Amazon" = 0, InstaCart = 0
//To find if an Item is present:
itemsMap.contains("Dark chocolate");
//Find prices from each service for that Item and size, and quantity
int reqSize = 10; //Assume req. size = 10
int reqQuantity = 5;
ArrayList<HashMap<String, String>> propsList = itemsMap.get("Dark chocolate")
for (HashMap<String, String> specificPropsMap : propsList) { //For each set of props
int size = Integer.parseInt(specificPropsMap.get("size"));
if (size == reqSize) {
String service = specificPropsMap.get("service"); //Say Amazon
int price = Integer.parseInt(specificPropsMap.get("price")); //Say 2
int initialPriceInCart = cartMap.get(service); //Initially 0
int finalPriceInCart = initialPriceInCart + price * reqQuantity;
cartMap.put(service, finalPriceInCart); //Cart price updated
}
}
//Find lowest priced service
String lowestPrice = Integer.MAX_VALUE; //Initially set as high as possible
String lowestService = "";
for (String key : cartMap.keySet()) {
if (cartMap.get(key) < lowestPrice) {
lowestPrice = cartMap.get(key);
lowestService = key;
}
}
General pointers that I can think of:
Population: Populate all these values initially while reading from the files.
Conversion : Convert values such as size, price to a standard (kg, cents/dollars, etc)
Naming : It's better to keep it descriptive (brand or brandName instead of bName)
Error handling : Add checks/try-catch blocks wherever necessary
Edit: Added steps. Might look a bit complex since we have some entries in the txt and some in the csv, but it's actually easy:
Read txt file; you now have a service and a csv file. Thus, for each service(outer loop)
Add the service as a key to cartMap if it's not already present
Create a new specificPropsMap, add service to this
Read the csv corresponding to that service. For each item(inner loop)
Store all props in the same specificPropsMap
You now have the prop item from the csv
Check if item is present in itemsMap
If present, skip to next step. If not, add item to the itemsMap as a key, with an empty List as value
Do itemsMap.get(item), you'll have the propsList
Add specificPropsMap to the propsList
Repeat for all items and all services.
I have a String that tells me what attribute I should use to make some filtering. How can I use this String to actually access the data in the object ?
I have a method that returns a List of strings telling me how to filter my List of objects. Such as:
String[] { "id=123", "name=foo" }
So my first idea was to split the String into 2 parts with:
filterString.split("=") and use the first part of the String (e.g. "id") to identify the attribute being filtered.
Coming for a JS background, I would do it like this:
const attr = filterString.split('=')[0]; // grabs the "id" part from the string "id=123", for example
const filteredValue = filterString.split('=')[1]; // grabs the "123" part from the string "id=123", for example
items.filter(el => el[`${attr}`] === filteredValue) // returns an array with the items where the id == "123"
How would I be able to do that with Java ?
You can use reflections to get fields of class by dynamic name.
#Test
void test() throws NoSuchFieldException, IllegalAccessException {
String[] filters = {"id=123", "name=foo"};
List<Item> list = newArrayList(new Item(123, "abc"), new Item(2, "foo"), new Item(123, "foo"));
Class<Item> itemClass = Item.class;
for (String filter : filters) {
String key = StringUtils.substringBefore(filter, "=");
String value = StringUtils.substringAfter(filter, "=");
Iterator<Item> iterator = list.iterator();
while (iterator.hasNext()) {
Item item = iterator.next();
Field field = itemClass.getDeclaredField(key);
field.setAccessible(true);
Object itemValue = field.get(item);
if (!value.equals(String.valueOf(itemValue))) {
iterator.remove();
}
}
}
assertEquals(1, list.size());
}
But I agree with comment from sp00m - it's slow and potentially dangerous.
This code should work :
//create the filter map
Map<String, String> expectedFieldValueMap = new HashMap<>();
for (String currentDataValue : input) {
String[] keyValue = currentDataValue.split("=");
String expectedField = keyValue[0];
String expectedValue = keyValue[1];
expectedFieldValueMap.put(expectedField, expectedValue);
}
Then iterate over input object list ( have used Employee class with id and name fields & prepared a test data list with few Employee objects called inputEmployeeList which is being iterated ) and see if all filters passes, using reflection, though slow, is one way:
for (Employee e : inputEmployeeList) {
try {
boolean filterPassed = true;
for (String expectedField : expectedFieldValueMap.keySet()) {
String expectedValue = expectedFieldValueMap.get(expectedField);
Field fieldData = e.getClass().getDeclaredField(expectedField);
fieldData.setAccessible(true);
if (!expectedValue.equals(fieldData.get(e))) {
filterPassed = false;
break;
}
}
if (filterPassed) {
System.out.println(e + " object passed the filter");
}
} catch (Exception any) {
any.printStackTrace();
// handle
}
}
I have a Set of data. For example:
car accord
car civic
suv landcruzer
suv landrover
muv innova
I want store it in a scanner or hash map and retrieve the values based on the input.
If "car" is the input I want to pass URL+/accord and URL+/civic as its output
If "muv" is the input, I want to pass URL+/innova as its output
String URL = "www.abc.com";
String Vehicletype = "";
#DataProvider(name = "irLanguage")
public Object[][] lang() {
#SuppressWarnings("resource")
Scanner s = new Scanner(
"Car /accord/\n" +
"Car /civic/\n" +
"suv /landcruzer/\n" +
"suv /rangerover/\n" +
"muv /innova/\n");
Map<String, List<String>> map = new LinkedHashMap<String, List<String>>();
while (s.hasNext()) {
String key = s.next();
if (!map.containsKey(key))
map.put(key, new LinkedList<String>());
map.get(key).add(s.next());
}
urlArray = map.get(vehicletype);
String[][] shades = new String[urlArray.size()][2];
for (int i = 0; i < urlArray.size(); i++) {
shades[i][0] = urlArray.get(i).toString();
shades[i][1] = URL + urlArray.get(i).toString();
lang = shades[i][0];
System.out.println(shades[i][0]);
}
return shades;
}
Here, the code is working fine. That is , if the input vehicle type is car then the output url is www.abc.com/accord/ and www.abc.com/civic/
and if the vehicle type is muv, it only returns www.abc.com/innova/ . This setup works fine for me. But, I wonder if there is any simpler method to do this.
Can anybody with good knowledge in java can help?
You have the right idea, I would build a HashMap that contains one Key (e.g. "car") and all the desired Values for that Key (e.g. "accord", "civic")
HashMap<String, ArrayList<String>> vehicles = new HashMap<String, ArrayList<String>>();
ArrayList<String> makes = new ArrayList<String>();
makes.add("accord");
makes.add("civic");
vehicles.put("car", makes);
makes.clear();
makes.add("landcruzer");
makes.add("rangerover");
vehicles.put("suv", makes);
makes.clear();
makes.add("innova");
vehicles.put("muv", makes);
makes.clear();
Now that you've got the vehicles HashMap built, you can fetch a Key and get all Values and build your URLs.
makes = vehicles.get("car");
for (String make : makes)
{
System.out.println("www.abc.com/" + make);
}
I have three input fields.
First Name
Last item
Date Of Birth
I would like to get random data for each input from a property file.
This is how the property file looks. Field name and = should be ignored.
- First Name= Robert, Brian, Shawn, Bay, John, Paul
- Last Name= Jerry, Adam ,Lu , Eric
- Date of Birth= 01/12/12,12/10/12,1/2/17
Example: For First Name: File should randomly select one name from the following names
Robert, Brian, Shawn, Bay, John, Paul
Also I need to ignore anything before =
FileInputStream objfile = new FileInputStream(System.getProperty("user.dir "+path);
in = new BufferedReader(new InputStreamReader(objfile ));
String line = in.readLine();
while (line != null && !line.trim().isEmpty()) {
String eachRecord[]=line.trim().split(",");
Random rand = new Random();
//I need to pick first name randomly from the file from row 1.
send(firstName,(eachRecord[0]));
If you know that you're always going to have just those 3 lines in your property file I would get put each into a map with an index as the key then randomly generate a key in the range of the map.
// your code here to read the file in
HashMap<String, String> firstNameMap = new HashMap<String, String>();
HashMap<String, String> lastNameMap = new HashMap<String, String>();
HashMap<String, String> dobMap = new HashMap<String, String>();
String line;
while (line = in.readLine() != null) {
String[] parts = line.split("=");
if(parts[0].equals("First Name")) {
String[] values = lineParts[1].split(",");
for (int i = 0; i < values.length; ++i) {
firstNameMap.put(i, values[i]);
}
}
else if(parts[0].equals("Last Name")) {
// do the same as FN but for lastnamemap
}
else if(parts[0].equals("Date of Birth") {
// do the same as FN but for dobmap
}
}
// Now you can use the length of the map and a random number to get a value
// first name for instance:
int randomNum = ThreadLocalRandom.current().nextInt(0, firstNameMap.size(0 + 1);
System.out.println("First Name: " + firstNameMap.get(randomNum));
// and you would do the same for the other fields
The code can easily be refactored with some helper methods to make it cleaner, we'll leave that as a HW assignment :)
This way you have a cache of all your values that you can call at anytime and get a random value. I realize this isn't the most optimum solution having nested loops and 3 different maps but if your input file only contains 3 lines and you're not expecting to have millions of inputs it should be just fine.
Haven't programmed stuff like this in a long time.
Feel free to test it, and let me know if it works.
The result of this code should be a HashMap object called values
You can then get the specific fields you want from it, using get(field_name)
For example - values.get("First Name"). Make sure to use to correct case, because "first name" won't work.
If you want it all to be lower case, you can just add .toLowerCase() at the end of the line that puts the field and value into the HashMap
import java.lang.Math;
import java.util.HashMap;
public class Test
{
// arguments are passed using the text field below this editor
public static void main(String[] args)
{
// set the value of "in" here, so you actually read from it
HashMap<String, String> values = new HashMap<String, String>();
String line;
while (((line = in.readLine()) != null) && !line.trim().isEmpty()) {
if(!line.contains("=")) {
continue;
}
String[] lineParts = line.split("=");
String[] eachRecord = lineParts[1].split(",");
System.out.println("adding value of field type = " + lineParts[0].trim());
// now add the mapping to the values HashMap - values[field_name] = random_field_value
values.put(lineParts[0].trim(), eachRecord[(int) (Math.random() * eachRecord.length)].trim());
}
System.out.println("First Name = " + values.get("First Name"));
System.out.println("Last Name = " + values.get("Last Name"));
System.out.println("Date of Birth = " + values.get("Date of Birth"));
}
}
I am looking for an idea how to accomplish this task. So I'll start with how my program is working.
My program reads a CSV file. They are key value pairs separated by a comma.
L1234456,ygja-3bcb-iiiv-pppp-a8yr-c3d2-ct7v-giap-24yj-3gie
L6789101,zgna-3mcb-iiiv-pppp-a8yr-c3d2-ct7v-gggg-zz33-33ie
etc
Function takes a file and parses it into an arrayList of String[]. The function returns the ArrayList.
public ArrayList<String[]> parseFile(File csvFile) {
Scanner scan = null;
try {
scan = new Scanner(csvFile);
} catch (FileNotFoundException e) {
}
ArrayList<String[]> records = new ArrayList<String[]>();
String[] record = new String[2];
while (scan.hasNext()) {
record = scan.nextLine().trim().split(",");
records.add(record);
}
return records;
}
Here is the code, where I am calling parse file and passing in the CSVFile.
ArrayList<String[]> Records = parseFile(csvFile);
I then created another ArrayList for files that aren't parsed.
ArrayList<String> NotParsed = new ArrayList<String>();
So the program then continues to sanitize the key value pairs separated by a comma. So we first start with the first key in the record. E.g L1234456. If the record could not be sanitized it then it replaces the current key with "CouldNOtBeParsed" text.
for (int i = 0; i < Records.size(); i++) {
if(!validateRecord(Records.get(i)[0].toString())) {
Logging.info("Records could not be parsed " + Records.get(i)[0]);
NotParsed.add(srpRecords.get(i)[0].toString());
Records.get(i)[0] = "CouldNotBeParsed";
} else {
Logging.info(Records.get(i)[0] + " has been sanitized");
}
}
Next we do the 2nd key in the key value pair e.g ygja-3bcb-iiiv-pppp-a8yr-c3d2-ct7v-giap-24yj-3gie
for (int i = 0; i < Records.size(); i++) {
if(!validateRecordKey(Records.get(i)[1].toString())) {
Logging.info("Record Key could not be parsed " + Records.get(i)[0]);
NotParsed.add(Records.get(i)[1].toString());
Records.get(i)[1] = "CouldNotBeParsed";
} else {
Logging.info(Records.get(i)[1] + " has been sanitized");
}
}
The problem is that I need both keyvalue pairs to be sanitized, make a separate list of the keyValue pairs that could not be sanitized and a list of the ones there were sanitized so they can be inserted into a database. The ones that cannot will be printed out to the user.
I thought about looping thought the records and removing the records with the "CouldNotBeParsed" text so that would just leave the ones that could be parsed. I also tried removing the records from the during the for loop Records.remove((i)); However that messes up the For loop because if the first record could not be sanitized, then it's removed, the on the next iteration of the loop it's skipped because record 2 is now record 1. That's why i went with adding the text.
Atually I need two lists, one for the Records that were sanitized and another that wasn't.
So I was thinking there must be a better way to do this. Or a better method of sanitizing both keyValue pairs at the same time or something of that nature. Suggestions?
Start by changing the data structure: rather than using a list of two-element String[] arrays, define a class for your key-value pairs:
class KeyValuePair {
private final String key;
private final String value;
public KeyValuePair(String k, String v) { key = k; value = v; }
public String getKey() { return key; }
public String getValue() { return value; }
}
Note that the class is immutable.
Now make an object with three lists of KeyValuePair objects:
class ParseResult {
private final List<KeyValuePair> sanitized = new ArrayList<KeyValuePair>();
private final List<KeyValuePair> badKey = new ArrayList<KeyValuePair>();
private final List<KeyValuePair> badValue = new ArrayList<KeyValuePair>();
public ParseResult(List<KeyValuePair> s, List<KeyValuePair> bk, List<KeyValuePair> bv) {
sanitized = s;
badKey = bk;
badValue = bv;
}
public List<KeyValuePair> getSanitized() { return sanitized; }
public List<KeyValuePair> getBadKey() { return badKey; }
public List<KeyValuePair> getBadValue() { return badValue; }
}
Finally, populate these three lists in a single loop that reads from the file:
public static ParseResult parseFile(File csvFile) {
Scanner scan = null;
try {
scan = new Scanner(csvFile);
} catch (FileNotFoundException e) {
???
// Do something about this exception.
// Consider not catching it here, letting the caller deal with it.
}
final List<KeyValuePair> sanitized = new ArrayList<KeyValuePair>();
final List<KeyValuePair> badKey = new ArrayList<KeyValuePair>();
final List<KeyValuePair> badValue = new ArrayList<KeyValuePair>();
while (scan.hasNext()) {
String[] tokens = scan.nextLine().trim().split(",");
if (tokens.length != 2) {
???
// Do something about this - either throw an exception,
// or log a message and continue.
}
KeyValuePair kvp = new KeyValuePair(tokens[0], tokens[1]);
// Do the validation on the spot
if (!validateRecordKey(kvp.getKey())) {
badKey.add(kvp);
} else if (!validateRecord(kvp.getValue())) {
badValue.add(kvp);
} else {
sanitized.add(kvp);
}
}
return new ParseResult(sanitized, badKey, badValue);
}
Now you have a single function that produces a single result with all your records cleanly separated into three buckets - i.e. sanitized records, records with bad keys, and record with good keys but bad values.