Given the below code, is there some reason that when the final if-else statement steps into the else clause, if I un-comment the two lines of code and comment the "FOOZANAZABAR" and "TESTCAIRO" lines, that it would not add those lines into the LinkedHashSet? It appears to add
values.add(new BigDecimal(PEUNIT).multiply(new BigDecimal(1000)).toString());
correctly when the logic drops into the else clause, but will not add the BD.ZERO or the PEFAMT to that field DESPITE the fact they are strings.
As a note, the ZERO and PEFAMT are BigDecimal's that are converted to a string. These are the only two values that are giving me grief. Any direction would be greatly appreciated.
public static LinkedHashMap<String, LinkedHashSet<String>> convertTransactionTableData(ResultSet rs) {
LinkedHashMap<String, LinkedHashSet<String>> returnableMap = new LinkedHashMap<String, LinkedHashSet<String>> ();
try {
while (rs.next()){
String PEFAMT, PEPOLN, MCISST, PEBRCD, PEEFFY, PEPLAN;
String PEUNIT, PETRNC, PECO, PEITYP, ZERO;
PEPOLN = rs.getString("PEPOLN");
MCISST = rs.getString("MCISST");
PEBRCD = rs.getBigDecimal("PEBRCD").toString();
PEEFFY = rs.getBigDecimal("PEEFFY").toString();
PEPLAN = rs.getString("PEPLAN");
PEUNIT = rs.getBigDecimal("PEUNIT").toString();
PEFAMT = rs.getBigDecimal("PEFAMT").toString();
PETRNC = rs.getString("PETRNC");
PECO = rs.getString("PECO");
PEITYP = DataConverter.resetInsuranceType(rs.getString("PEITYP"));
ZERO = BigDecimal.ZERO.toPlainString();
String policyNumber = PEPOLN;
LinkedHashSet<String> values = new LinkedHashSet<String>();
values.add(MCISST);
values.add(PEBRCD);
values.add(PEEFFY);
values.add(PEPLAN);
values.add(PEUNIT);
if (PEPLAN.equalsIgnoreCase("HSRE")) {
values.add(new BigDecimal(PEUNIT).multiply(new BigDecimal(1000)).toString());
} else {
values.add(PEFAMT);
}
values.add(PETRNC);
values.add(PECO);
values.add(PEITYP);
if (DataConverter.testStringToInt(PETRNC)) {
if (Integer.valueOf(PETRNC) >= 20 && Integer.valueOf(PETRNC) <= 29) {
values.add(PEFAMT);
values.add(ZERO);
values.add(ZERO);
} else {
values.add("FOOZANZABAR");
values.add("TESTCAIRO");
// values.add(ZERO);
// values.add(PEFAMT);
values.add(new BigDecimal(PEUNIT).multiply(new BigDecimal(1000)).toString());
}
}
returnableMap.put(policyNumber, values);
}
} catch (SQLException sqlEx) {
logger.error("Problem converting the ResultSet. ", sqlEx);
}
return returnableMap;
}
Thank you in advance.
Josh
Please note that the underlying data structure you're using here is a SET which means it won't let you add duplicates. In all probability, the string values of BD.ZERO and PEFAMT must already be present in your values set and are hence getting ignored.
If this turns out to be the case simply switch to using LinkedList<String> that allows you to have duplicates.
Related
This is my whole code, it's quite complex but please help me. It's taken me for 2 days but I failed:
public static ArrayList<DocGia> XuatDocGia() throws IOException {
ArrayList<DocGia> listDocGia = new ArrayList<>();
File fileDocGia = new File("fileDocGia.txt");
if(fileDocGia.exists() == false) {
System.out.println("Chưa có đọc giả nào trong thư viện");
} else {
BufferedReader br = new BufferedReader(new FileReader("fileDocGia.txt"));
if (br.readLine() == null) {
System.out.println("Chưa có đọc giả nào trong thư viện");
} else {
int soDong = DemSoDong("fileDocGia.txt");
int dongHienTai = 0;
Scanner fileScanner = new Scanner(fileDocGia);
for(int i = 0, z = 0;;i++, z++) {
DocGia docGia = null;
System.out.println("***Đọc giả thứ: " + (i+1));
docGia.tendocgia = fileScanner.nextLine();
if(i >= 1) {
docGia.tendocgia = fileScanner.nextLine();
}
docGia.maDocGia = fileScanner.nextLine();
docGia.soSachmuon = fileScanner.nextInt();
docGia.thoiGianMuonSach = fileScanner.nextInt();
listDocGia.add(docGia);
docGia.XuatDocGia();
dongHienTai += 4;
if(dongHienTai == soDong) {
fileScanner.close();
break;
}
}
}
for(DocGia docGia: listDocGia) {
docGia.XuatDocGia();
}
}
return listDocGia;
}
look at my code, when i run:
docGia.XuatDocGia();
-> the value of every single element is right at debug. it also means the value of the variable inside is right. but at the end of this function. i run
for(DocGia docGia: listDocGia) {
docGia.XuatDocGia();
}
this is XuatDocGia funtion:
public static void XuatDocGia(){
System.out.println(tendocgia);
System.out.println(maDocGia);
System.out.println(soSachmuon);
System.out.println(thoiGianMuonSach);
}
It just shows for me the last element in this ArrayList, repeat in 3 times( equal the number of elements).
I think a problem come from adding process of listDocGia.add(docGia);
You guys no need to bother everything else in my code, because i know it's really complex. I have tested carefully, just focus on my problem.
I'm so sorry because i'm Vietnamese and beginner at Java. The next time everything will be English. Thank you so much.
If this is the actual code, you are adding null references to your List, but since you are using a static method to print the values, you don't get a NullPointerException. Assuming your code passes compilation, this means all the members of the DocGia class are static, which explains why you get the same values in each iteration of your loop.
You should change
DocGia docGia = null;
to
DocGia docGia = new DocGia ();
and change all the members of DocGia (including the XuatDocGia method that prints them) to be non static.
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.
I have verified that the entity I am looking for is in the datastore. I have verified that the list I pass as a method parameter contains this entity. I am trying to find all objects that have their 'userGmail' contained in the list of strings I pass.
Here is my code
#SuppressWarnings("unchecked")
#ApiMethod(name = "findFriendsByEmailList")
public CollectionResponse<ZeppaUser> findFriendsByEmailList(
#Named("emailsList") List<String> emailsList, User user)
throws OAuthRequestException {
if (user == null) {
throw new OAuthRequestException(
"Null User Authorization Exception, findFriendsByEmailList");
}
PersistenceManager mgr = null;
List<ZeppaUser> execute = null;
Query query = null;
try {
mgr = getPersistenceManager();
query = mgr.newQuery(ZeppaUser.class);
query.declareParameters("java.util.List emailListParam");
query.setFilter("emailListParam.contains( userGmail )");
execute = (List<ZeppaUser>) query.execute(emailsList);
query.closeAll();
} finally {
mgr.close();
}
return CollectionResponse.<ZeppaUser> builder().setItems(execute)
.build();
}
This is the stack trace I receive from it:
Something worth noting: I do not receive this error on lists I pass in that to not contain an element found in the datastore. Just when it does exist which leads me to believe that the Query has located the element but has not been closed or executed into a return parameter correctly. If it is preferable to return List that is more than ok. I have tried multiple variations of this with no success thus far. It is getting quite frustrating.
Ok so I found a way around it.
Lists cannot be passed into ApiEndpoints. That or I didn't figure out the correct way to do it and would LOVE an update on the proper way to do this.
Instead, in my client, I construct a String of emails seperated by a comma and send a string into the parameter as an 'encoded' string list then 'decode' it upon execution. Works well but seems hacky.
here are the methods I used. This is convenient though because it works with iOS as well.
public static String encodeListString(ArrayList<String> stringList){
StringBuilder stringbuilder = new StringBuilder();
stringbuilder.append(stringList.get(0));
if(stringList.size() > 1){
for( int i = 0; i < stringList.size(); i++){
stringbuilder.append(",");
stringbuilder.append(stringList.get(i));
}
}
return stringbuilder.toString();
}
public static List<String> decodeListString(String encodedString){
char[] characters = encodedString.toCharArray();
StringBuilder stringbuilder = new StringBuilder();
int position = 0;
ArrayList<String> stringList = new ArrayList<String>();
while(true){
try {
char character = characters[position];
if(character == ','){
String resultString = stringbuilder.toString();
stringList.add(resultString);
stringbuilder = new StringBuilder(); // clear it
} else {
stringbuilder.append(character);
}
position++;
} catch (ArrayIndexOutOfBoundsException aiex){
// List ended
String resultString = stringbuilder.toString();
if(!resultString.isEmpty())
stringList.add(resultString);
break;
}
}
return stringList;
}
I have a pretty introductory question that I hope can get answered rather easily.
Currently I am trying to write something that queries my DB, returns result set (list of account id's) and then sets those account id's into an array so that I can populate an object with the values.
My object is going to be used as input into another method I have written but I can't figure out how I go about populating my account_id field on it with the values in my array that I returned in the result set. There doesn't seem to be any "setter" methods for lack of a better term on my array of type String.
I was able to get the array to populate with acct_id's from the result set and print them out so I know that I do have information coming back.
Below is the snippet I currently have, any help/improvements I could make would be greatly appreciated!
try {
connection = DriverManager.getConnection(url, user, password);
st = connection.createStatement();
rs = st.executeQuery(sql);
List<Long> array = new ArrayList<Long>();
while (rs.next()) {
array.add((long) rs.getLong("acct_id"));
for (Integer i = 0; i < array.size(); i++) {
System.out.println(array.get(i));
GetSummaryRequest request = new GetSummaryRequest();
request.accountKey = new AccountDTO(array[i]);
}
}
} catch (SQLException e) {
System.out.println("Connection failed.");
e.printStackTrace();
return;
}
if (rs.next()) {
System.out.println(rs.getString(1));
} else
System.out.print("Failed. Try again");
}
If my understanding is correct you may need the code below which is used to store all the account id's inside an array and you can use this to pass as a parameter to another method.
ArrayList<GetSummaryRequest> array1=new ArrayList<GetSummaryRequest>();
GetSummaryRequest request = new GetSummaryRequest();
while (rs.next())
{
request=new GetSummaryRequest();
request.accountKey=rs.getString("acct_id");
array1.add(request);
}
Now you have ArrayList of GetSummaryRequest with accountKey for each object.
if i understand correctly accountkey is integer right?
you can use Integer.parseint('your string!') class to convert the string to int.
i hope it helps
First of all , storing newline separated values in one column is not a good practice. This is against atomicity principle and will lead you to problems soon - ex., total number of accounts? how do you find it?
Once you convince yourself with this, you can use only one loop like this
List<GetSummaryRequest> summaryRequests = new ArrayList<GetSummaryRequest>();
while (rs.next()) {
String em = rs.getString("acct_id");
GetSummaryRequest request = new GetSummaryRequest();
request.accountKey = em;
summaryRequests.add(request);
}
return summaryRequests;
Probably you need something like that:
// First you get all ids
List<String> accountsIds = new ArrayList<String>();
while (rs.next()) {
accountsIds.add(rs.getString("acct_id"));
}
// Then iterate ids
for (String id : accountsIds) {
GetSummaryRequest request = new GetSummaryRequest();
request.accountKey = id;
}
In my Java code I have embedded a SQL query which fetches data from a database and stores it in a result-set. I want to add a function or a piece of code which will take only non-negative data from the result-set for further processing.
Assumption: The result set can contain positive/negative/zero data values as well as characters. Also i cannot change the SQL query as its out of my scope.
try something like this, i think it will do the job
private ArrayList getNegativeNumbers(ResultSet rs, String coulumnName ) throws SQLException
{
ArrayList ret = new ArrayList();
while(rs.next()){
try {
int x = rs.getInt(coulumnName);
if(x>=0){
ret.add(new Integer(x));
}
} catch (Exception ex) {
String x = rs.getString(coulumnName);
ret.add(x);
}
}
return ret;
}
UPDATED 2. Sorry for my edits, i missread the question
while (resultSet.next()) {
if(resultSet.getInt("Column name") > 0);
Processmethod(resultSet.getInt("Column name") );
}