How create in java a properties with one to many relationship? [duplicate] - java

This question already has answers here:
Multiple values in java.util.Properties
(5 answers)
Closed 2 years ago.
i have a file where i save one key with some entry (relation one to many).
From this file i need to extract values searching by key.
I just found a util (java.util.Properties) to handle properties files in Java.
It works very well for properties files.
But its return the first occurence for the key searched.
Since is present for properties files i expect that already exist also a version with multiple results allowed.
Exist a solution that returns an array of string for the researched key?

Properties is backed by a Hashtable so the key must be unique.
So if you want to stick to multiple instances of the same key you can implement the parsing yourself (if you don't depend too much on the extras managed by Properties):
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
public class FileInput {
Properties porp;
public static Map<String, List<String>> loadProperties(String file) throws IOException
{
HashMap<String, List<String>> multiMap = new HashMap<>();
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line = null;
while ((line = br.readLine()) != null) {
if (line.startsWith("#"))
continue; // skip comment lines
String[] parts = line.split("=");
multiMap.computeIfAbsent(parts[0].trim(), k -> new ArrayList<String>()).add(parts[1].trim());
}
}
return multiMap;
}
public static void main(String[] args) throws IOException {
Map<String,List<String>> result=loadProperties("myproperties.properties");
}
}
UPDATED: improved exception handling (valid remark #rzwitsersloot). I prefer to throw the exception so the caller can decide what to do if the properties file is missing.

Related

Java Iterator is skipping half elements

I wrote a small scripts to read from CSV in java. It takes a CSV, and push some values from the CSV into an HashMap. My CSV has 110 records ( 109 without the header ) however i get an HashMap with 54 values. When i debug, i can see that at each iteration, a line from my CSV is skipped.
Here's the code
package **CENSORED**.utils;
import com.day.cq.dam.api.Asset;
import com.day.cq.dam.api.Rendition;
import com.day.text.csv.Csv;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
public class DateFormatUtils {
private static String dateFormatCsvPath = "/content/dam/csv/country_date_format.csv";
public static String getDateFormatByLocale(Locale Locale, ResourceResolver resourceResolver) {
Resource res = resourceResolver.getResource(dateFormatCsvPath);
Asset asset = res.adaptTo(Asset.class);
Rendition rendition = asset.getOriginal();
InputStream is = rendition.adaptTo(InputStream.class);
HashMap<String, String> localeToFormat = new HashMap<String, String>();
Csv csv = new Csv();
try {
Iterator<String[]> rowIterator = csv.read(is, StandardCharsets.UTF_8.name());
while (rowIterator.hasNext()) {
String[] row = rowIterator.next();
String country = row[1];
String locale = row[4];
String dateFormat = row[6];
localeToFormat.put(locale.toLowerCase() + "_" + country.toLowerCase(), dateFormat);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Here are few screenshot of my debug
at 1st iteration, the line 2 of my CSV gets added into my hashmap. The header have been skipped.
At 2nd iteration, the line 5 gets added to my hashmap, but lines 3-4 aren't.
At 3rd iteration, the line 8 gets added to my hasmap, but lines 6-7 aren't.
At the end i end up with 53 elements in my hashmap while i expect 109.
Here's also a sample of my CSV :
ISO 3166 Country Code,ISO639-2 Country Code,Country,ISO 3166 Country Code,ISO639-2 Lang,Language,Date Format
ALB,AL,Albania,sqi,sq,Albanian,yyyy-MM-dd
ARE,AE,United Arab Emirates,ara,ar,Arabic,dd/MM/yyyy
ARG,AR,Argentina,spa,es,Spanish,dd/MM/yyyy
AUS,AU,Australia,eng,en,English,d/MM/yyyy
AUT,AT,Austria,deu,de,German,dd.MM.yyyy
BEL,BE,Belgium,fra,fr,French,d/MM/yyyy
BEL,BE,Belgium,nld,nl,Dutch,d/MM/yyyy
BGR,BG,Bulgaria,bul,bg,Bulgarian,yyyy-M-d
BHR,BH,Bahrain,ara,ar,Arabic,dd/MM/yyyy
BIH,BA,Bosnia and Herzegovina,srp,sr,Serbian,yyyy-MM-dd
BLR,BY,Belarus,bel,be,Belarusian,d.M.yyyy
BOL,BO,Bolivia,spa,es,Spanish,dd-MM-yyyy
BRA,BR,Brazil,por,pt,Portuguese,dd/MM/yyyy
CAN,CA,Canada,fra,fr,French,yyyy-MM-dd
CAN,CA,Canada,eng,en,English,dd/MM/yyyy
Finally a last screenshot that shows that my CSV has correct EOL at their line
This is the csv.read() function, a class made by Adobe for AEM :
public Iterator<String[]> read(InputStream in, String charset) throws IOException {
if (charset == null) {
charset = System.getProperty("file.encoding");
}
InputStream in = new BufferedInputStream(in, 4096);
this.input = new InputStreamReader(in, charset);
return this.read();
}
I finally went with another solution since i wasnt able to use this one. For perennity, i was developing this for an AEM project; i decided to leverage the Generic List Item in ACS-common to get a dictionnary with all the values i needed instead of reading from a CSV. As #Artistotle stated, there is def something wrong with the reader so i'd advise against using com.day.text.csv.Csv;

How to store multiple columns of a csv dataset in a single variable in java so that the variable can be used as input feature for ml model

I have done this in python. Here is my python code:
Here X is the input variable in which I stored all the
input columns of csv file and y is the target variable.
dataset=pandas.read_csv("newone.csv")
features = [0,1,4,5,6,7]
X =dataset.iloc[:,features]
y =dataset.iloc[:,2]
How can I do this in java?
Here is my java code in which I read the csv file but
I am able to store only one column value of the csv in a variable.
public static void main(String[] args) throws IOException {
BufferedReader reader = Files.newBufferedReader(Paths.get("C:/Users/N/Desktop/newone.csv"));
CSVParser csvParser = new CSVParser(reader,
CSVFormat.DEFAULT.withHeader("Enounter", "Relation", "Event", "Tag","Encounter_no", "Diagonosis", "User_Id", "Client_Id").withIgnoreHeaderCase().withTrim());
for (CSVRecord csvRecord : csvParser) {
encntr=csvRecord.get("Encounter");
}
}
----------
Consider using MyKong's code on how to read CSV files in Java. Something like the following snippet below (heavily borrowed from MyKong's better version):
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
String[] valuesFromLine = line.split(cvsSplitBy);
String secondValue = valuesFromLine[1];
// do something with second value
}
This depends entirely on what the relationship between your columns is like. It is impossible to answer this question in a general manner as this changes from dataset to dataset and even from algorithm to algorithm, but here are a few approaches you might like to try:
Use Principal Component Analysis to identify if there any variables in your desired tuple of columns you can omit because they contribute very little to the row class variable.
Use Feature Hashing to reduce the dimensionality of your dataset by bundling together related properties (this does not work as a blanket solution - indeed, nothing in ML ever does. Try it before you commit to it).
If the columns you'd like to unite are numerical, you may want to think of an algorithm to join them in a unique way, or a way which makes sense. If they are categorical, a sparse one-hot bit vector may help you.
Download these jar https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml/3.15 and https://mvnrepository.com/artifact/org.apache.poi/poi/3.15
and add them to your build path
import java.io.FileInputStream;
import java.io.IOException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ExcelReader {
public static void main(String[] args) throws IOException
{
//specify your file path
FileInputStream file = new FileInputStream("D:\\test.xlsx");
XSSFWorkbook workbook = new XSSFWorkbook(file);
//to fetch sheet
XSSFSheet sheet = workbook.getSheetAt(0);
// for iterating through rows
for(int c=0;c<=sheet.getLastRowNum();c++)
{
// for iterating through columns
Row rows = sheet.getRow(c);
for(int b=0;b<=rows.getLastCellNum();b++)
{
Cell cells=rows.getCell(b);
//to read cell value as string
String comp=cells.getStringCellValue();
}
}
}
}

Delete specific rownumbers in .csv file using java

For ex: I am trying search a text with name "abc"in .csv file which is present in column no 6 in multiple rows and I need to delete those rows.
I tried below code. I am able to get the line no/row no where text "abc" is present in column 6 but it is not deleting the rows.
import java.io.BufferedReader;
import java.io.*;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
public class ReadExcel {
public static void main(String[] args) throws Exception{
String csvFile = "csv filelocation";
CSVReader reader = new CSVReader(new FileReader(csvFile));
List<String[]> allElements = reader.readAll();
String [] nextLine;
int lineNumber = 0;
while ((nextLine = reader.readNext()) != null) {
lineNumber++;
if(nextLine[5].equalsIgnoreCase("abc")){
System.out.println("Line # " + lineNumber);
allElements.remove(lineNumber);
}
}
For reading the files in CSV format, I am currently using the library super-csv. There are various examples.
Let me know if you need help to use it.
So, if you would like to use the opencsv library, I start a new example for writing the new content in a CSV file. I take inspiration from your example code.
List<String[]> allElements; /* This list will contain the lines that cover your criteria */
/*
...
*/
CSVWriter writer = new CSVWriter(new FileWriter("yourfile.csv"));
writer.writeAll(allElements);
writer.close();

Deleting Duplicates in a List

I am managing an email listserv for my club. I need to sort the email addresses from a txt file, delete the duplicates, and then ouput them so that I may easily organize them. Most of my code is spliced together from various sources online since I have very minimal programming skills right now. This is what I have so far:
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
public class ReadAllLines {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Path textFile_path = Paths.get("V:/", "Entrepreneurship Club Email List.txt");
Charset charset = Charset.forName("ISO-8859-1");
try {
//Reads txt file
List<String> lines = Files.readAllLines(textFile_path, charset);
//Sorts txt file alphabetically
Collections.sort(lines);
//prints txt file
for (String line : lines) {
System.out.println(line);
}
//File Not Found Error
} catch (IOException e) {
System.out.println(e);
}
}
}
I need to sort the email addresses from a txt file, delete the duplicates, and then ouput them so that I may easily organize them.
In that case, use a SortedSet
Set<String> set = new TreeSet<>(Files.readAllLines(textFile_path, charset));
set will be sorted with duplicates ignored.
In Java 8, you can do
Set<String> set = Files.lines(textFile_path, charset)
.sorted()
.collect(toSet());

Java - how to Read a properties file into array [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
All - I am a newbie to java. So need some help or code
where the properties file is like
test.properties
100
200
300
400
I want to read it into an single array, so that the input data that I get, i can check if its within the array or not.
I could actually hard code the like if id=100 or id=200 or id=300 {then do somethings} else { do something ordo nothing} .
I was able to find the answer for it: Going to add the code here
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
public class read_properties_into_array {
private static List<String> sensitivePropertiesList=new ArrayList<String>();
public static void main(String[] args) {
try {
File file = new File("test.properties");
FileInputStream fileInput = new FileInputStream(file);
Properties properties = new Properties();
properties.load(fileInput);
fileInput.close();
Enumeration enuKeys = properties.keys();
while (enuKeys.hasMoreElements()) {
String key = (String) enuKeys.nextElement();
sensitivePropertiesList.add(new String(key));
//String value = properties.getProperty(key);
//System.out.println(key);
}
System.out.println("hi I am here");
System.out.println("lenght of list:"+sensitivePropertiesList.size());
for(int i=0;i<sensitivePropertiesList.size();i++)
{
System.out.println(sensitivePropertiesList.get(i));
}
System.out.println("Check if 100 it exists.");
if (sensitivePropertiesList.contains("100"))
{
System.out.println(" 100 it exists.");
}
else
{
System.out.println(" 100 Does not exist.");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Please add the test.properties file at the java project level if using eclipse.
Test.properties
100
200
300
Though your question is not clear, I think you don't need a properties class to read an array from. You put key=value pairs in a properties file.
You should first read a file using java IO, then put all values in an array and finally iterate over that array and check for your value.
Check for some code here:
https://stackoverflow.com/a/7705672/841221
If you don't use a Java Properties file, but rather something like
test.properties
100
200
300
You could read all lines into a List and work later on that list.
Path inputFile = Paths.get("test.properties");
Charset fileCharset = Charset.defaultCharset();
List<String> allValues = Files.readAllLines(inputFile, fileCharset);
// work on that list
for (String value : allValues) {
System.out.println(value);
}

Categories