Get single line and multiple line values from text file - java

I use following Java code to get specific values from a text file, which contains key-value pairs in different order.
if(nfo_file.exists() && !nfo_file.isDirectory()) {
Scanner scanner = new Scanner(nfo_file);
Map<String, String> values = new HashMap<>();
String line, key = null, value = null;
while (scanner.hasNextLine()) {
line = scanner.nextLine();
if (line.contains(":")) {
if (key != null) {
values.put(key, value.trim());
}
int indexOfColon = line.indexOf(":");
key = line.substring(0, indexOfColon);
value = line.substring(indexOfColon + 1);
} else {
value += " " + line;
}
}
for (Map.Entry<String, String> entry : values.entrySet()) {
if (entry.getKey().startsWith("Description")) {
nfodata[0] = entry.getValue();
}
Input text file example:
Num: 10101
Name: File_8
Description: qwertz qwertz
qwertz (qwertz) ztrewq?
Neque porro quisquam est qui
Quantity: 2
It doesn't work in some cases, it doesn't read one liners and sometimes read only first line of a multiline value.

It looks like your code will not add the last key-value pair to the Map.
Try:
while (scanner.hasNextLine()) {
line = scanner.nextLine();
if (line.contains(":")) {
if (key != null) {
values.put(key, value.trim());
key = null;
value = null;
}
int indexOfColon = line.indexOf(":");
key = line.substring(0, indexOfColon);
value = line.substring(indexOfColon + 1);
} else {
value += " " + line;
}
}
if (key != null) {
values.put (key, value.trim());
}

Related

How to map<String,Integer> two csv column with respect to their values in Java? [duplicate]

This question already has answers here:
Reading CSV file line by line and parsing it
(2 answers)
Read CSV file column by column
(8 answers)
Closed 4 years ago.
I am a new bee in Java and want to map CSV columns according to their values.
My orignal csv data is like:
name,salary,address
AAA,1000,kkk
BBB,880,lll
AAA,90,kkk
CCC,700,mmm
BBB,700,lll
Expected output should be in Hashmap Key Value pair of two columns name and salary like:
Key: AAA Value 1090
Key: BBB Value 1580
Key: CCC Value 700
This is my code:
String line = "";
InputStreamReader inStream = new
InputStreamReader(uc.getInputStream());
buff = new BufferedReader(inStream);
try {
while ((line = b.readLine()) != null) {
String[] fields = parseCsvLine(line);
// I dont know what to do here
}
b.close();
Log.d("Get data from API", "Processing Stop");
} catch (IOException e) {
e.printStackTrace();
}
public String[] parseCsvLine(String line) {
// Create a pattern to match breaks
Pattern p =
Pattern.compile(",(?=([^\"]*\"[^\"]*\")*(?![^\"]*\"))");
// Split input with the pattern
String[] fields = p.split(line);
for (int i = 0; i < fields.length; i++) {
// Get rid of residual double quotes
fields[i] = fields[i].replace("\"", "");
}
return fields;
}
What you want is to split your line data into part. Then accumulate it to a Map
Map<String, Integer> result = new HashMap<>();
while ((line = b.readLine()) != null) {
String[] parts = line.split(","); // Split your line, take `,` as delimeter
String key = parts[0]; // This is your 'AAA'
Integer value = Integer.parseInt(parts[1]); // This is your 1000
if (result.get(key) == null) {
result.put(key, value);
} else {
result.put(key, result.get(key) + value); // There's already a value here, add it with new value
}
}
The ugly part:
if (result.get(key) == null) {
result.put(key, value);
} else {
result.put(key, result.get(key) + value); // There's already a value here, add it with new value
}
Can replaced with new Java 8 Map utility:
result.putIfAbsent(key, value); // Put (key, value) if key is absent from the map
result.compute(key, value, (k, v) -> v + value);

Java adding unique values to hashmap <string, string>

I made a java program that will check contents of directory and generate for each file a md5 checksum. When the program is done it will save it to a CSV file. So far the lookup of files is working perfectly except that when writing to the CSV i want to make to only add new detected files. I think the issue lies with the md5 string used as key is not correctly found.
Here is an excerpt of the CSV file:
4d1954a6d4e99cacc57beef94c80f994,uiautomationcoreapi.h;E:\Tools\Strawberry-perl-5.24.1.1-64\c\x86_64-w64-mingw32\include\uiautomationcoreapi.h;N/A
56ab7135e96627b90afca89199f2c708,winerror.h;E:\Tools\Strawberry-perl-5.24.1.1-64\c\x86_64-w64-mingw32\include\winerror.h;N/A
146e5c5e51cc51ecf8d5cd5a6fbfc0a1,msimcsdk.h;E:\Tools\Strawberry-perl-5.24.1.1-64\c\x86_64-w64-mingw32\include\msimcsdk.h;N/A
e0c43f92a1e89ddfdc2d1493fe179646,X509.pm;E:\Tools\Strawberry-perl-5.24.1.1-64\perl\vendor\lib\Crypt\OpenSSL\X509.pm;N/A
As you can see first is the MD5 as key and afterwards is a long string containing name, location and score that will be split with the ; character.
and here is the code that should make sure only new ones are added:
private static HashMap<String, String> map = new HashMap<String,String>();
public void UpdateCSV(HashMap<String, String> filemap) {
/*Set set = filemap.entrySet();
Iterator iterator = set.iterator();
while(iterator.hasNext()) {
Map.Entry mentry = (Map.Entry) iterator.next();
String md = map.get(mentry.getKey());
System.out.println("checking key:" + md);
if (md == null) {
String[] line = mentry.getValue().toString().split(";");
System.out.println("Adding new File:" + line[0]);
map.put(mentry.getKey().toString(), mentry.getValue().toString());
}
}*/
for (final String key : filemap.keySet()) {
String md = map.get(key.toCharArray());
if (md == null) {
System.out.println("Key was not found:" + key);
String[] line = filemap.get(key).toString().split(";");
System.out.println("Adding new File:" + line[0]);
map.put(key, filemap.get(key));
}
}
}
As you can see from the commented code i tried in different ways already. hashmap filemap is the current status of the folder structure.
To read the already saved CSV file is use the following code:
private void readCSV() {
System.out.println("Reading CSV file");
BufferedReader br = new BufferedReader(filereader);
String line = null;
try {
while ((line = br.readLine()) != null) {
String str[] = line.split(",");
for (int i = 0; i < str.length; i++) {
String arr[] = str[i].split(":");
map.put(arr[0], arr[1]);
System.out.println("just added to map" + arr[0].toString() + " with value "+ arr[0].toString() );
}
}
}
catch(java.io.IOException e) {
System.out.println("Can't read file");
}
}
So when i run the program it will say that all files are new even tough they are already known in the CSV. So can anyone help to get this key string checked correctly?
As #Ben pointed out, your problem is that you use String as key when putting, but char[] when getting.
It should be something along the lines:
for (final String key : filemap.keySet()) {
map.computeIfAbsent(key, k -> {
System.out.println("Key was not found:" + k);
String[] line = filemap.get(k).toString().split(";");
System.out.println("Adding new File:" + line[0]);
return filemap.get(k);
});
}
Since you need both key as well as value from filemap, you actually better iterate over entrySet. This will save you additional filemap.gets:
for (final Map.Entry<String, String> entry : filemap.entrySet()) {
final String key = entry.getKey();
final String value = entry.getValue();
map.computeIfAbsent(key, k -> {
System.out.println("Key was not found:" + k);
String[] line = value.split(";");
System.out.println("Adding new File:" + line[0]);
return value;
});
}

Replace space in a String with replaceAll not working in JAVA

I try to remove a space into a string which contains a int type value.
I read a .csv file with the scanner methode.
I use a Class to set/get the data.
I format data into the setter of the class.
Input data example:
String Pu_ht = "1 635,90";
Basic Example:
/**
* #param Pu_ht the Pu_ht to set
*/
public void setPu_ht(String Pu_ht) {
this.Pu_ht = Pu_ht.replace(",", ".").replace(".00", "");
}
Tried example:
/**
* #param Pu_ht the Pu_ht to set
*/
public void setPu_ht(String Pu_ht) {
this.Pu_ht = Pu_ht.replace(",", ".").replace(".00", "").replaceAll("\\s+", "");
}
Other example:
/**
* #param Pu_ht the Pu_ht to set
*/
public void setPu_ht(String Pu_ht) {
this.Pu_ht = Pu_ht.replace(",", ".").replace(".00", "").replaceAll(" ", "");
}
Output data example: 1 635.90
I tried a lots of things but nothing work for my case.
Best regards
EDIT:
My code:
public void requete_pommes() throws IOException, ClassNotFoundException, SQLException {
// open file input stream
BufferedReader reader = new BufferedReader(new FileReader(filename));
// read file line by line
String line = null;
Scanner scanner = null;
int index = 0;
List<Pommes> pomList = new ArrayList<>();
boolean firstLine = false;
while ((line = reader.readLine()) != null) {
if (!(line.equals(";;;;TOTAL HT"))) {
if (!(line.equals(";;;;"))) {
Pommes pom = new Pommes();
scanner = new Scanner(line);
scanner.useDelimiter(";");
while (scanner.hasNext()) {
String data = scanner.next();
pom.setNumero_compte("21826");
if ((index == 0)) {
pom.setReference(data);
} else if ((index == 1)) {
pom.setDesignation(data);
} else if ((index == 2)) {
pom.setQte(data);
} else if ((index == 3)) {
if(data.equals("1 635,90")){
data = data.replaceAll("\\s","");
System.err.println("data: " + data);
}
pom.setPu_ht(data);
} else if ((index == 4)) {
pom.setMontant_HT(data);
} else {
System.out.println("invalid data::" + data);
}
pom.setNumero_commande("1554");
index++;
}
index = 0;
pomList.add(pom);
requeteCorps = "(( SELECT codea FROM article WHERE tarif7 != 'O' AND tarif8 = 'O' AND pvente > 0 AND COALESCE(trim( reffou), '') != '' AND reffou = '" + pom.getReference() + "' ), " + pom.getQte() + " , " + pom.getPu_ht() + ", '" + kapiece + "', 'stomag','vendu', getnum('LCK')),";
ar.add(requeteCorps);
}
}
}
The value "1 635,90" probably stems from a locale specific format, and the "space" actually is a non-breaking space, \u00A0. This is done often to prevent in flexible width text representation a line break to happen inside a number.
s = s.replace("\u00A0", "");
String Pu_ht = "1 635,90";
System.out.println(Pu_ht.replace(",", ".").replace(".00", "").replaceAll("\\s+", ""));
just put the above codes in main method and execute. the output will be 1635.90,then examine your codes.

Handle Empty lines in Java

I am facing a problem in the following code. I am trying to run the program and it terminates when it hits empty space in my input. How else I should approach this.
try {
BufferedReader sc = new BufferedReader(new FileReader(text.txt);
ArrayList<String> name = new ArrayList<>();
ArrayList<String> id = new ArrayList<>();
ArrayList<String> place = new ArrayList<>();
ArrayList<String> details = new ArrayList<>();
String line = null;
while ((line = sc.readLine()) !=null) {
if (!line.trim().equals("")) {
System.out.println(line);
if (line.toLowerCase().contains("name")) {
name.add(line.split("=")[1].trim());
}
if (line.toLowerCase().contains("id")) {
id.add(line.split("=")[1].trim());
}
if (line.toLowerCase().contains("location")) {
place.add(line.split("=")[1].trim());
}
if (line.toLowerCase().contains("details")) {
details.add(line.split("=")[1].trim());
}
}
}
PrintWriter pr = new PrintWriter(new File(text.csv));
pr.println("Name;Id;;Location;Details");
for (int i = 0; i < name.size(); i++) {
pr.println(name.get(i) + ";" + id.get(i) + ";" + place.get(i) + ";" + details.get(i));
}
pr.close();
sc.close();
} catch (Exception e) {
e.printStackTrace();
} }
My Input looks like
name = abc
id = 123
place = xyz
details = hsdyhuslkjaldhaadj
name = ert
id = 7872
place =
details = shahkjdhksdhsala
name = sfd
id = 4343
place = ksjks
Details = kljhaljs
when im trying to execute then above text my program terminates at place = "null" because of no value there.I need the output as an empty space created in place ="null" and print the rest as follows in a .csv file
If you process the location, line.split("=")[1] could result in an ArrayIndexOutOfBoundException and line.split("=")[1].trim() could result in a NullPointerException.
You can avoid this by testing your parsed result.
Instead of place.add(line.split("=")[1].trim());, do place.add(parseContentDefaultEmpty(line));, with:
private String parseContentDefaultEmpty(final String line) {
final String[] result = line.split("=");
if(result.length <= 1) {
return "";
}
final String content = line.split("=")[1];
return content != null ? content.trim() : "";
}
First there is a issue,your input file contains key as "place" but your are trying for word "location"
if (line.toLowerCase().contains("location")) { //this must be changed to place
place.add(line.split("=")[1].trim());
}
Modified the code snippet as below.check it
while ((line = sc.readLine()) != null) {
if (!line.trim().equals("")) {
System.out.println(line);
if (line.toLowerCase().contains("name")) {
name.add(line.split("=")[1].trim());
}
if (line.toLowerCase().contains("id")) {
id.add(line.split("=")[1].trim());
}
if (line.toLowerCase().contains("place")) {
// change done here to add space if no value
place.add(line.split("=").length > 1 ? line.split("=")[1]
.trim() : " ");
}
if (line.toLowerCase().contains("details")) {
details.add(line.split("=")[1].trim());
}
}
}
Setting question to line doesn't appear to change what line is read later (if you're wanting the line to advance before it hits the while loop).

method to return hashmap from text

I am trying to write a method that takes an InputStream variable and returns a HashMap back to main. However I'm stuck on how to return the variable of HashMap. New to Java so I do not know what I'm doing wrong.For the return statement: pairsCount cannot be resolved to variable. Thanks in advance.
private static Map<String, Integer> getHashMap(InputStream in)
{
if (in != null)
{
// Using a Scanner object to read one word at a time from the input stream.
#SuppressWarnings("resource")
Scanner sc = new Scanner(in);
String word;
System.out.println(" - Assignment 1 -s%n%n\n");
// Continue getting words until we reach the end of input
List<String> inputWords = new ArrayList<String>();
while (sc.hasNext())
{
word = sc.next();
if (!word.equals(null))
{
inputWords.add(word);
}
}
Map<String, Integer> pairsCount = new HashMap<>();
Iterator<String> it = inputWords.iterator();
String currentWord = null;
String previousWord = null;
Integer wordCount = 0;
while(it.hasNext())
{
currentWord = it.next();
if( previousWord != null )
{
String key = previousWord.concat( "#" ).concat( currentWord );
if( pairsCount.containsKey( key ) )
{
Integer lastCount = pairsCount.get( key );
pairsCount.put( key, lastCount + 1 );
wordCount = wordCount + lastCount;
}
else
{
pairsCount.put( key, 1 );
wordCount = 1;
}
}
previousWord = currentWord;
}
}
return (pairsCount);
}
This is probably because variable pairsCount is out of its scope.
You define it inside of the if block but trying to return it outside.
So try define Map pairsCount = new HashMap<>();
before the if (in != null)

Categories