Matching Keys in a HashMap - java

I am attempting to do the following (in psuedocode):
Generate HashMapOne that will be populated by results
found in a DICOM file (the Key was manipulated for matching
purposes).
Generate a second HashMapTwo that will be read from a
text document.
Compare the Keys of both HashMaps, if a match add the results of
the value of HashMapOne in a new HashMapThree.
I am getting stuck with adding the matched key's value to the HashMapThree. It always populates a null value despite me declaring this a public static variable. Can anyone please tell me why this may be? Here is the code snippets below:
public class viewDICOMTags {
HashMap<String,String> dicomFile = new HashMap<String,String>();
HashMap<String,String> dicomTagList = new HashMap<String,String>();
HashMap<String,String> Result = new HashMap<String, String>();
Iterator<org.dcm4che2.data.DicomElement> iter = null;
DicomObject working;
public static DicomElement element;
DicomElement elementTwo;
public static String result;
File dicomList = new File("C:\\Users\\Ryan\\dicomTagList.txt");
public void readDICOMObject(String path) throws IOException
{
DicomInputStream din = null;
din = new DicomInputStream(new File(path));
try {
working = din.readDicomObject();
iter = working.iterator();
while (iter.hasNext())
{
element = iter.next();
result = element.toString();
String s = element.toString().substring(0, Math.min(element.toString().length(), 11));
dicomFile.put(String.valueOf(s.toString()), element.vr().toString());
}
System.out.println("Collected tags, VR Code, and Description from DICOM file....");
}
catch (IOException e)
{
e.printStackTrace();
return;
}
finally {
try {
din.close();
}
catch (IOException ignore){
}
}
readFromTextFile();
}
public void readFromTextFile() throws IOException
{
try
{
String dicomData = "DICOM";
String line = null;
BufferedReader bReader = new BufferedReader(new FileReader(dicomList));
while((line = bReader.readLine()) != null)
{
dicomTagList.put(line.toString(), dicomData);
}
System.out.println("Reading Tags from Text File....");
bReader.close();
}
catch(FileNotFoundException e)
{
System.err.print(e);
}
catch(IOException i)
{
System.err.print(i);
}
compareDICOMSets();
}
public void compareDICOMSets() throws IOException
{
for (Entry<String, String> entry : dicomFile.entrySet())
{
if(dicomTagList.containsKey(entry.getKey()))
Result.put(entry.getKey(), dicomFile.get(element.toString()));
System.out.println(dicomFile.get(element.toString()));
}
SortedSet<String> keys = new TreeSet<String>(Result.keySet());
for (String key : keys) {
String value = Result.get(key);
System.out.println(key);
}
}
}

This line of code looks very wrong
Result.put(entry.getKey(), dicomFile.get(element.toString()));
If you are trying to copy the key/value pair from HashMapOne, then this is not correct.
The value for each key added to Result will be null, because you are calling get method on Map interface on dicomFile. get requires a key as a lookup value, and you are passing in
element.toString()
where element will be the last element that was read from your file.
I think you should be using
Result.put(entry.getKey(), entry.getValue()));

Related

Append to existing CSV with headers

I have a method that appends to a .csv file but the problem is that it adds a header row everytime as well. How can I append to the .csv correctly?
I am aware that adding to a List would do the job but this method is called in separate runs.
public static void writeToCSVFileAndSend(String facilityId, int candidateStockTakeContainersCount) throws IOException {
FileWriter report = new FileWriter("/tmp/MonthlyExpectedComplianceSuggestions.csv", true);
LocalDate today = java.time.LocalDate.now();
String[] headers = { "Warehouse", "Expected Count for "+ today.getMonth().getDisplayName(TextStyle.SHORT, Locale.ENGLISH)};
Map<String, Integer> facilityExpectedMonthlyCountMap= new HashMap<String, Integer>() {
{
put(facilityId, candidateStockTakeContainersCount);
}
};
try (CSVPrinter printer = new CSVPrinter(report, CSVFormat.DEFAULT
.withHeader(headers))) {
facilityExpectedMonthlyCountMap.forEach((a, b) -> {
try {
printer.printRecord(a, b);
} catch (IOException e) {
e.printStackTrace();
}
});
}
}
Current Output
Warehouse,Expected Count for Dec
A,2147
Warehouse,Expected Count for Dec
B,0
Expected Output
Warehouse,Expected Count for Dec
A,2147
B,0
To avoid multiple headers, you should create object of CSVPrinter once and reuse it
Depending on how you are getting the data, you may split the function in two and pass CSVPrinter object around.
public static void writeToCSVFileAndSend() throws IOException
{
File outputCSV = new File( "/tmp/MonthlyExpectedComplianceSuggestions.csv");
LocalDate today = java.time.LocalDate.now();
String[] headers = { "Warehouse", "Expected Count for "+ today.getMonth().getDisplayName(TextStyle.SHORT, Locale.ENGLISH)};
boolean headerRequired = true;
if( outputCSV.exists()){
headerRequired = false;
}
CSVPrinter printer = null;
if( headerRequired){
printer = new CSVPrinter(report, CSVFormat.DEFAULT.withHeader(headers));
}
else{
printer = new CSVPrinter(report);
}
// Iterate through combination of facilityId and candidateStockTakeContainersCount and
// call print record
Map<String, Integer> facilityExpectedMonthlyCountMap= new HashMap<String, Integer>();
// fill in your data in map here
facilityExpectedMonthlyCountMap.forEach((a, b) -> {
try {
printer.printRecord(a, b);
} catch (IOException e) {
e.printStackTrace();
}
});
}

HASHMAP, key present still giving "false" result

Following is my code that returning false even if the key exists:
import java.util.HashMap;
import java.util.Map;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class SequenceNumber {
public static int getSequenceNumber (String TcOrderId){
// Create a hash map to set key values pair.
Map<String, Integer> map = new HashMap<String, Integer>();
int i= 1;
// check if hashmap contains the key.
System.out.println("key present " +map.containsKey(TcOrderId));
if (map.containsKey(TcOrderId))
{
//Key Present
System.out.println("Inside IF ");
int value = map.get(TcOrderId);
System.out.println("value from the key " + value);
map.remove(value);
map.put(TcOrderId, value+1);
return map.get(TcOrderId);
}
else
{
//Key Not present
System.out.println("INSIDE ELSE ");
map.put(TcOrderId, i);
System.out.println("map "+ map);
return map.get(TcOrderId);
}
}
public static void main(String[] args) throws IOException {
String sCurrentLine;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("C:\\Users\\BongAn\\Desktop\\Package\\testing.txt"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
{
while ((sCurrentLine = br.readLine()) != null) {
//String orderid = sCurrentLine.substring(0, 6);
System.out.println("reading line " +sCurrentLine);
int seqvalue = getSequenceNumber(sCurrentLine);
System.out.println("seqvalue "+seqvalue);
}
}
}
}
Input data in the file:
1233
1233
1234
The result should be
1
2
1
But everytime its going in the else loop and the result is
1
1
1
I am trying to use HASHMAP as I am creating my own index.
In your CODE everytime you call getSequenceNumber function - you create new HashMap. I believe this is not something you want.
To avoid that - you can simply move Map<String, Integer> map = new HashMap<String, Integer>(); into the body of class. Since the function getSequenceNumber is a static function - you will need to make the variable static. Hope this helps.
Snippet:
public class SequenceNumber {
// PUT STATIC VARIABLE HERE:
static Map<String, Integer> map = new HashMap<String, Integer>();
public static int getSequenceNumber (String TcOrderId){
// Create a hash map to set key values pair.
// (REMOVE) Map<String, Integer> map = new HashMap<String, Integer>();**
int i= 1;
// check if hashmap contains the key.
...
}
...
}
Another alternative
(perhaps better) would be to avoid static functions and variables and create an instance of SequenceNumber object. That way you could keep a couple of different instance numbers separately.
Simple snippet:
public class SequenceNumber {
// Your hashmap here:
Map<String, Integer> map = new HashMap<String, Integer>();
public int getSequenceNumber (String TcOrderId) {
// ...
}
public static void main(String[] args) throws IOException {
// Instance of SequenceNumber object:
SequenceNumber sequenceNumber = new SequenceNumber();
String sCurrentLine;
BufferedReader br = null;
// ...
while ((sCurrentLine = br.readLine()) != null) {
//String orderid = sCurrentLine.substring(0, 6);
System.out.println("reading line " +sCurrentLine);
int seqvalue = sequenceNumber.getSequenceNumber(sCurrentLine);
System.out.println("seqvalue "+seqvalue);
}
// ...
}
}
Something like this should work. Haven't tried running it though.
public class SequenceNumber {
public static int getSequenceNumber (String TcOrderId, Map<String, Integer> map){
if(!map.contains(TcOrderId)){
map.put(TcOrderId, 0);
}
map.put(TcOrderId, map.get(TcOrderId)+1);
return map.get(TcOrderId);
}
public static void main(String[] args) throws IOException {
String sCurrentLine;
BufferedReader br = null;
Map<String, Integer> map = new HashMap<String, Integer>();
try {
br = new BufferedReader(new FileReader("C:\\Users\\BongAn\\Desktop\\Package\\testing.txt"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
{
while ((sCurrentLine = br.readLine()) != null) {
//String orderid = sCurrentLine.substring(0, 6);
System.out.println("reading line " +sCurrentLine);
int seqvalue = getSequenceNumber(sCurrentLine, map);
System.out.println("seqvalue "+seqvalue);
}
}

Ordering keys in .properties file alphabetically while ignoring case sensitivity

I have this function that stores values from a .properties file into a tree map (translatedMap), then retrieves new values from "keyMap" and stores them into "translatedMap" as well. The issue is no matter what I do it seems to always separate capitalized keys from non-capitalized keys. Here is my code:
Properties translation = new Properties(){
private static final long serialVersionUID = 1L;
#Override
public synchronized Enumeration<Object> keys() {
return Collections.enumeration(new TreeSet<Object>(super
.keySet()));
}
};
//creates file and stores values of keyMap into the file
try {
TreeMap<String, String> translatedMap = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
InputStreamReader in = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
translation.load(in);
// Store all values to TreeMap and sort
Enumeration<?> e = translation.propertyNames();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
if (key.matches(".#")) {
} else {
String value = translation.getProperty(key);
translatedMap.put(key, value);
}
}
// Add new values to translatedMap
for (String key : keyMap.keySet()) {
// Handle if some keys have already been added; delete so they can be re-added
if (translatedMap.containsKey(key)) {
translatedMap.remove(key);
}
translatedMap.put(key, keyMap.get(key));
}
in.close();
translation.putAll(translatedMap);
File translationFile = new File(filePath);
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(translationFile, false), "UTF-8");
translation.store(out, null);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
The output I'm getting is something like:
CAPITALIZED_KEY1=value1 CAPITALIZED_KEY2=value2
alowercase.key=value3 anotherlowercase.key=value4
morelowercase.keys=value5
When I would want it to come out like:
alowercase.key=value3 anotherlowercase.key=value4
CAPITALIZED_KEY1=value1 CAPITALIZED_KEY2=value2
morelowercase.keys=value5
Properties are not ordered. It doesn't matter what order you insert into them or if you call putAll() with something that is sorted, they extend Hashtable. See here.
The basic problem is that - though sorted case-insensitive -, an ordered map should still be case-sensitive as property names are case-sensitive.
Hence overide Properties, and on writing sort the names case-insensitive.
public class SortedProperties extends Properties {
#Override
public void store(Writer writer, String comments)
throws IOException {
List<String> names = new ArrayList<>();
for (Enumeration<?> en = propertyNames(); en.hasMoreElements(); ) {
String name = en.nextElement().toString();
names.add(name);
}
Collections.sort(names, new Comparator<String>() {
#Override
public int compareTo(String other) {
toLowerCase().compareTo(other.toLowerCase());
}
});
//... write all properties
}
To achieve this I ended up avoiding the store function all together. I did the sorting inside the treeMap. I used a buffered writter and wrote to the file. like this:
Properties translation = new Properties();
//creates file and stores values of keyMap into the file
try {
TreeMap<String, String> translatedMap = new TreeMap<String, String>(new Comparator<String>() {
public int compare(String o1, String o2) {
return o1.toLowerCase().compareTo(o2.toLowerCase());
}
});
InputStreamReader in = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
translation.load(in);
// Store all values to TreeMap and sort
for (String key : translation.stringPropertyNames()) {
keyMap.put(key, translation.getProperty(key));
}
in.close();
Iterator<String> it = keyMap.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
translatedMap.put(key, keyMap.get(key));
}
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath, false), "UTF-8"));
bw.write("#" + new Date().toString());
bw.newLine();
Iterator<String> it2 = translatedMap.keySet().iterator();
while (it2.hasNext()) {
String key = it2.next();
bw.write(key + '=' + translatedMap.get(key));
bw.newLine();
}
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}

edit .doc file header java

I need to edit .doc & .docx files header and maintain the style of the document.
I tried doing it by using:
poi api : I managed to read the file header but couldn't find how to replace a text in it and save the result with the original style .
public static void mFix(String iFilePath , HashMap<String, String> iOldNewCouples)
{
aOldNewCouples = iOldNewCouples;
try {
if(iFilePath==null)
return;
File file = new File(iFilePath);
FileInputStream fis=new FileInputStream(file.getAbsolutePath());
HWPFDocument document=new HWPFDocument(fis);
WordExtractor extractor = new WordExtractor(document); // read the doc as rtf
String fileData = extractor.getHeaderText();
String fileDataResult =fileData ;
for (Entry<String, String> entry : aOldNewCouples.entrySet())
{
if(fileData.contains(entry.getKey())) {
System.out.println("replace " +entry.getKey());
fileDataResult = fileData.replace(entry.getKey(), entry.getValue());
}
}
document.getHeaderStoryRange().replaceText(fileData, fileDataResult);
saveWord(iFilePath ,document);
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace( );
}
}
private static void saveWord(String filePath, HWPFDocument doc) throws FileNotFoundException, IOException
{
FileOutputStream fileOutputStream = null;
try{
fileOutputStream = new FileOutputStream(new File(filePath.replace(".doc", "-test.doc")));
BufferedOutputStream buffOutputStream = new BufferedOutputStream(fileOutputStream);
doc.write(buffOutputStream);
buffOutputStream.close();
fileOutputStream.close();
}
finally{
if( fileOutputStream != null)
fileOutputStream.close();
}
}
I tried doc4j api for docx : I found how to edit the header but didn't found how to keep the style.
public static void mFix(String iFilePath , HashMap<String, String> iOldNewCouples) {
aOldNewCouples = iOldNewCouples;
WordprocessingMLPackage output;
try {
output = WordprocessingMLPackage.load(new java.io.File(iFilePath));
replaceText(output.getDocumentModel().getSections().get(0).getHeaderFooterPolicy().getDefaultHeader());
output.save(new File(iFilePath));
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void replaceText(ContentAccessor c) throws Exception
{
for (Object p: c.getContent())
{
if (p instanceof ContentAccessor)
replaceText((ContentAccessor) p);
else if (p instanceof JAXBElement)
{
Object v = ((JAXBElement) p).getValue();
if (v instanceof ContentAccessor)
replaceText((ContentAccessor) v);
else if (v instanceof org.docx4j.wml.Text)
{
org.docx4j.wml.Text t = (org.docx4j.wml.Text) v;
String text = t.getValue();
if (text != null)
{
boolean flag = false;
for (Entry<String, String> entry : aOldNewCouples.entrySet())
{
if(text.contains(entry.getKey())) {
flag =true;
text = text.replaceAll(entry.getKey(), entry.getValue());
t.setSpace("preserve");
t.setValue(text);
}
}
}
}
}
}
}
I would like to have examples for those api.
If there is other free solution for this for Java projects , please write them with example.
thanks
Tami

I'm getting a Null pointer exception in my code because of the hashmap not being filled or maybe not

I was given this exercise:
Implement the following class that loads and prints a set of data values.
import java.util.Iterator;
public class MyLoader {
public void loadAndPrintValues(Iterator<String> keysToLoad, Data data, Printer printer) {
// Load data values like this:
// String value = data.loadValue(key);
// Print loaded data value like this:
// printer.printEntry(key, value);
}
}
However when I did the exercise I got a NullPointerException, probably from the while (keysToLoad.hasNext()) or from the key = keysToLoad.next();. I assume I got the exception because "data" was not getting filled but I can't figure out how to do it. Here is my code and error message
public interface Data{
//I made this method
public void makeEntry(String key, String value);
//given
public String loadValue(String key);
}
public interface Printer {
public void displayEntry(String key, String value);
}
import java.util.Iterator;
import java.util.HashMap;
public class MyLoader implements Data, Printer {
Data data; // = new MyLoader();
Printer printer; // = new MyLoader();
Iterator<String> iter; // = new MyLoader();
String key = "";
String value = "";
HashMap<String, String> ht = new HashMap<String, String>();
public MyLoader(){
// this.database = null;
// this.key = null;
// this.value = null;
// this.ht = null;
// this.iter = null;
System.out.println("now in the constructor");
}
public MyLoader(Iterator<String> iter, Data data, Printer printer){
this.data = data;
this.printer = printer;
this.iter = iter;
}
public void loadAndPrintValues(Iterator<String> keysToLoad, Data data, Printer printer) {
try {
if (ht.isEmpty()){
System.out.println("ht is empty");
throw new NullPointerException("Database is empty.");
}else {
this.data = data;
}
while (keysToLoad.hasNext()){
// Load data values like this:
key = keysToLoad.next();
value = data.loadValue(key);
// Print loaded data value like this:
printer.printEntry(key, value);
}
}catch (NullPointerException npe){
System.out.println("caught null pointer ");
System.out.println(npe.getMessage());
}
}
#Override
public void makeEntry(String key, String value){
ht.put(key, value);
}
#Override
public void printEntry(String key, String value) {
System.out.println("[" + key + " : " + value + "]");
}
#Override
public String loadValue(String key) {
System.out.println("loadValue:" + key);
if(this.ht.containsKey(key))
return this.ht.get(key);
else {
System.out.println("No key in database.");
throw new NullPointerException("No key in data.");
}
}
}
public class test {
public static void main(String[] args) {
try {
MyLoader mdbl = new MyLoader();
mdbl.makeEntry("0", "zero");
mdbl.makeEntry("1", "One");
mdbl.makeEntry("2", "Two");
mdbl.makeEntry("3", "Three");
mdbl.loadAndPrintValues(mdbl.iter, mdbl.data, mdbl.printer);
}
catch(NullPointerException e){
System.out.println(e.getMessage());
}
}
}
mdbl.iter is never assigned a value, i.e. is null (by default, since you are using the MyLoader constructor without arguments in which iter is not assigned). So when you pass it to a method that tries to do operations on it, you naturally get a NullPointerException (not an error).
You should not have
try{ /* ... */ } catch (NullPointerException npe){ /* ... */ }
blocks because any decent IDE will allow you to get to the line where the exception was thrown with one click, which is not the case if you catch the exception and simply print a message to System.out.
You are passing null values for Iterator, Data and Printer parameter of the method loadAndPrintValues() which will result in NullPointerException.
in this line
mdbl.loadAndPrintValues(mdbl.iter, mdbl.data, mdbl.printer);
you didn't initialize the mdbl.data and mdbl.printer
Never ever catch a NullPointerException. Remove the catch block with NullPointerException, run it and then post the stack trace.

Categories

Resources