ArrayList remove function removing wrong object - java

The code looks like this:
for (int i = 0; i < fileList.size(); i++) {
System.out.println("File List size is " + fileList.size());
String fileName = (fileList.get(i).fileName);
String accountNumber = accountNumber(fileName);
System.out.println(accountNumber);
if(accountNumber.equals("fail")) {
decode(dirLocation+fileName,"C:/.../.../.../ChunkTestInvalid/"+fileName);
fileList.remove(i);
System.out.println("File removed at first stage: "+fileName);
}
else {..........
I'm trying to setup a situation where files that don't match criteria in the accountNumber method get decoded to a particular folder on my machine and removed from fileList, which is an ArrayList for a custom Object. The fileList.remove(i) call is removing SOMETHING from the ArrayList (as the fileList.size() value is decreasing) but it's removing something other the object located at fileList.get(i) at the start of the for loop, because it keeps returning the same object.
What is the correct way to identify that the object I want to remove from the ArrayList is the one that exists at fileList.get(i) at that time?

You can try using iterator like this -
List<String> fileList;
Iterator<String> iter = fileList.iterator();
while (iter.hasNext()) {
System.out.println("File List size is " + fileList.size());
String fileName = (iter.next().fileName);
String accountNumber = accountNumber(fileName);
System.out.println(accountNumber);
if(accountNumber.equals("fail")) {
decode(dirLocation+fileName,"C:/.../.../.../ChunkTestInvalid/"+fileName);
iter.remove();
System.out.println("File removed at first stage: "+fileName);
}
else {..........
}

Related

Get number of entries in properties file apache commons

I'm creating a list of IP address' to ping in which a user can add to the list which is then saved to a properties file in the form of site.name1 = ... site.name2 = ...
Currently I have a for loop with a fixed amount, is there a way to get the number of entries in a properties file so I can set this in the for loop rather than wait for a exception?
PropertiesConfiguration config = configs.properties(new File("IPs.properties"));
//initially check for how many values there are - set to max increments for loop
for (int i = 0; i < 3; i++) { //todo fix
siteName = config.getString("site.name" + i);
siteAddress = config.getString("site.address" + i);
SiteList.add(i, siteName);
IPList.add(i, siteAddress);
}
I've looked through the documentation and other questions but they seem to be unrelated.
It looks to me based on the documentation you should be able to use PropertiesConfiguration#getLayout#getKeys to get a Set of all keys as a String.
I had to modify the code a bit to use apache-commons-configuration-1.10
PropertiesConfiguration config = new PropertiesConfiguration("ips.properties");
PropertiesConfigurationLayout layout = config.getLayout();
String siteName = null;
String siteAddress = null;
for (String key : layout.getKeys()) {
String value = config.getString(key);
if (value == null) {
throw new IllegalStateException(String.format("No value found for key: %s", key));
}
if (key.equals("site.name")) {
siteName = value;
} else if (key.equals("site.address")) {
siteAddress = value;
} else {
throw new IllegalStateException(String.format("Unsupported key: %s", key));
}
}
System.out.println(String.format("name=%s, address=%s", siteName, siteAddress));

String cannot be added to List using Object in Java

I am working on a JSF based Web Application where I read contents from a file(dumpfile) and then parse it using a logic and keep adding it to a list using an object and also set a string using the object. But I keep getting this error. I am confused where I am wrong. I am a beginner so can anyone be kind enough to help me?
List<DumpController> FinalDumpNotes;
public List<DumpController> initializeDumpNotes()
throws SocketException, IOException {
PostProcessedDump postProcessedDump = (PostProcessedDump) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("postProcessedDump");
List<DumpController> FinalNotes = new ArrayList<>();
if (postProcessedDump.getDumpNotes() == null) {
dumpNotes = new DumpNotes();
}
DumpListController dlcon = (DumpListController) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("dumpListController");
DumpInfo dumpinfo = dlcon.getSelectedDumpInfo();
String fileName = dumpinfo.getDate() + dumpinfo.getTime() + dumpinfo.getSeqNo() + dumpinfo.getType() + dumpinfo.getTape() + dumpinfo.getDescription() + ".txt";
if (checkFileExistsInWin(fileName)) {
postProcessedDump.setDumpnotescontent(getFileContentsFromWin(fileName));
String consolidateDumpnotes = getFileContentsFromWin(fileName);
String lines[];
String content = "";
lines = consolidateDumpnotes.split("\\r?\\n");
List<String> finallines = new ArrayList<>();
int k = 0;
for (int i = 0; i < lines.length; i++) {
if (!lines[i].equalsIgnoreCase("")) {
finallines.add(lines[i]);
k++;
}
}
for (int j = 0; j < finallines.size(); j++) {
if (finallines.get(j).startsWith("---------------------SAVED BY")) {
PostProcessedDump dump = new PostProcessedDump();
dump.setDumpMessage(content);
content = "";
FinalDumpNotes.add(dump);
} else {
content = content + finallines.get(j);
}
}
}
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("postProcessedDump", postProcessedDump);
return FinalDumpNotes;
}
I get the following error:
If you want to add instances of type PostProcessedDump to your List you should change it's type. Also, don't forget to initialize it. Something like,
List<PostProcessedDump> FinalDumpNotes = new ArrayList<>();
Also, Java naming convention is to start variable names with a lower case letter. FinalDumpNotes looks like a class, I would suggest something like
List<PostProcessedDump> processedList = new ArrayList<>();
Problems with your code:
List<DumpController> FinalDumpNotes;
You declare FinalDumpNotes to be a List of DumpController objects, but you never initialize it. In addition, your IDE is barfing on the following line of code:
FinalDumpNotes.add(dump);
because you are attempting to add a PostProcessedDump object to the List instead of a DumpController object.
For starters, you need to initialize your list like this:
List<DumpController> finalDumpNotes = new ArrayList<DumpController>();
Notice that I have made the variable name beginning with lower case, which is the convention (upper case is normally reserved for classes and interfaces).
I will leave it to you as a homework assignment to sort out the correct usage of this List.

Printing a HashMap into a .txt file

Right now, I'm trying to get this method of mine to print a .txt file of a HashMap that contains a word as a Key, and the number of times it appears in a read .txt file (done in another method) as a Value. The method needs to put the HashMap Keys in alphabetical order, and then print the corresponding Value next to it in a separate .txt file.
Here is my code for the method:
public static void writeVocabulary(HashMap<String, Integer> vocab, String fileName) {
// Converts the given HashMap keys (the words) into a List.
// Collections.sort() will sort the List of HashMap keys into alphabetical order.
List<String> listVal = new ArrayList<String>(vocab.keySet());
Collections.sort(listVal);
try
{
// Creating the writer
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(fileName)));
for (int i = 1; i < listVal.size(); i++) {
out.println(listVal.get(i) + " " + vocab.get(i));
}
out.close();
}
// Catching the file not found error
// and any other errors
catch (FileNotFoundException e) {
System.err.println(fileName + "cannot be found.");
}
catch (Exception e) {
System.err.println(e);
}
}
My problem is that, while a .txt file is printed, and the words are in perfect ASCII order (what I need), every value next to the word is returned null. I've tried many different ways of fixing this but to no avail. I think the problem is in my 'for' loop:
for (int i = 1; i < listVal.size(); i++) {
out.println(listVal.get(i) + " " + vocab.get(i));
}
I'm pretty sure my logic in this is faulty but I can't think of a solution. Any help would be much appreciated. Thanks in advance!
You need to use the correct map key to get the value from the map - this code currently uses the index in the List, not the value in the list (which is the actual key to the map).
for (int i = 0; i < listVal.size(); i++) {
out.println(listVal.get(i) + " " + vocab.get(listVal.get(i)));
}
And also start at index 0 if you want all the items (see initial condition in loop above). As suggested in a comment, you can alternatively use a TreeMap to iterate over the keys of the map in order
This is where an enhanced for loop would have kept you from making a mistake. You get values from a Map by using get(key):
for ( String key : listVal ) {
out.println( key + " " + vocab.get(key) );
}
You don't need to iterate through the list using the indexes; instead you can use:
for ( final String key : listVal ) {
out.println( key + " " + vocab.get( key ) );
}
and you can simplify things even further using a TreeSet to do the sorting:
for ( final String key : new TreeSet<String>( vocab.keySet() ) ) {
out.println( key + " " + vocab.get( key ) );
}

how to get highest version of record from a list

I have nearly 500 file. each file has nearly 5 version or 10 version with the same name. each file distinguish start with file name followed by semicolon then version number.
example:
Test.pdf;1
Test.pdf;2
Test.pdf;3
so i am getting list of file by doing this:
File file = new File(Path + "\\");
File[] fileList = file.listFiles();
List<String> namesList = new ArrayList<String>();
for (int i = 0; i < fileList.length; i++) {
String name=fileList[i].getName();
if(name.contains(".pdf")||name.contains(".excel")){
namesList.add(name);
}
for (int i = 0; i < namesList.size(); i++) {
String name = namesList.get(i);
}
How to get only highest version file i.e test.pdf;3
Use a Map to map each file name to a version. Iterate over your file names extract the name part and the version part and then compare the version with a previously saved one in the map. If there is no version for a name in the map then put the actual version in the Map as the highest.
You could try something like this:
#Test
public void listHighestVersion() {
String[] fileNames = {
"Test.pdf;1", "Test.pdf;2", "Test.pdf;3",
"Test.excel;1", "Test.excel;4", "Test.excel;3",
};
Map<String, Integer> fileVersionMap = new HashMap<>();
for(String fileNameWithVersion : fileNames) {
String[] split = fileNameWithVersion.split(";", 2);
if(split.length > 1) {
String fileName = split[0];
Integer fileVersion;
try {
fileVersion = Integer.parseInt(split[1]);
} catch(NumberFormatException e) {
fileVersion = 0;
}
Integer version = fileVersionMap.get(fileName);
if(version == null || fileVersion > version) {
fileVersionMap.put(fileName, fileVersion);
}
}
}
System.out.println(fileVersionMap);
}
output is:
{Test.excel=4, Test.pdf=3}
You can use the code shown below:
String[] files = {"test.pdf;3","test.pdf;1","differentTest.pdf;2","test.pdf;5","test.pdf;4", "test.excel;3","test.excel;1","test.excel;6","test.excel;5","test.excel;4"};
HashMap <String, Integer> newestFiles = new HashMap<String, Integer>();
for (String currentString : files) {
String currentFileName = currentString.split(";")[0];
Integer currentFileVersion = Integer.parseInt(currentString.split(";")[1]);
if (newestFiles.containsKey(currentFileName)) {
if (newestFiles.get(currentFileName) < currentFileVersion) {
newestFiles.put(currentFileName, currentFileVersion);
}
}
else {
newestFiles.put(currentFileName, currentFileVersion);
}
}
for (Entry<String, Integer> maxValue : newestFiles.entrySet()) {
String result = new StringBuilder("Max version of file: ").append(maxValue.getKey()).append(" is: ").append( maxValue.getValue()).toString();
System.out.println(result);
}
Result:
Max version of file: test.excel is: 6
Max version of file: test.pdf is: 5
Max version of file: differentTest.pdf is: 2
What is done here:
For every file get its name and version - using splitting.
Then check if you already processed files with that name (all processed are stored in newestFiles Map).
If it was not processed add it to the Map with current file
version (in else statement).
If it was processed check if
current version is bigger. If it is, substitute the file in the map.
Create a class say FileDetail with 2 attributs i.e. String fileName and integer version as attributes.
create List<FileDetail> as you are creating namesList
Implement comparable or comparator for class FileDetail and implement your sorting logic.

Parse string, using default methods

I have used the following code to extract text from .odt files:
public class OpenOfficeParser {
StringBuffer TextBuffer;
public OpenOfficeParser() {}
//Process text elements recursively
public void processElement(Object o) {
if (o instanceof Element) {
Element e = (Element) o;
String elementName = e.getQualifiedName();
if (elementName.startsWith("text")) {
if (elementName.equals("text:tab")) // add tab for text:tab
TextBuffer.append("\\t");
else if (elementName.equals("text:s")) // add space for text:s
TextBuffer.append(" ");
else {
List children = e.getContent();
Iterator iterator = children.iterator();
while (iterator.hasNext()) {
Object child = iterator.next();
//If Child is a Text Node, then append the text
if (child instanceof Text) {
Text t = (Text) child;
TextBuffer.append(t.getValue());
}
else
processElement(child); // Recursively process the child element
}
}
if (elementName.equals("text:p"))
TextBuffer.append("\\n");
}
else {
List non_text_list = e.getContent();
Iterator it = non_text_list.iterator();
while (it.hasNext()) {
Object non_text_child = it.next();
processElement(non_text_child);
}
}
}
}
public String getText(String fileName) throws Exception {
TextBuffer = new StringBuffer();
//Unzip the openOffice Document
ZipFile zipFile = new ZipFile(fileName);
Enumeration entries = zipFile.entries();
ZipEntry entry;
while(entries.hasMoreElements()) {
entry = (ZipEntry) entries.nextElement();
if (entry.getName().equals("content.xml")) {
TextBuffer = new StringBuffer();
SAXBuilder sax = new SAXBuilder();
Document doc = sax.build(zipFile.getInputStream(entry));
Element rootElement = doc.getRootElement();
processElement(rootElement);
break;
}
}
System.out.println("The text extracted from the OpenOffice document = " + TextBuffer.toString());
return TextBuffer.toString();
}
}
now my problem occurs when using the returned string from getText() method.
I ran the program and extracted some text from a .odt, here is a piece of extracted text:
(no hi virtual x oy)\n\n house cat \n open it \n\n trying to....
So I tried this
System.out.println( TextBuffer.toString().split("\\n"));
the output I received was:
substring: [Ljava.lang.String;#505bb829
I also tried this:
System.out.println( TextBuffer.toString().trim() );
but no changes in the printed string.
Why this behaviour?
What can I do to parse that string correctly?
And, if I wanted to add to array[i] each substring that ends with "\n\n" how can I do?
edit:
Sorry I made a mistake with the example because I forgot that split() returns an array.
The problem is that it returns an array with one line so what I'm asking is why doing this:
System.out.println(Arrays.toString(TextBuffer.toString().split("\\n")));
has no effect on the string I wrote in the example.
Also this:
System.out.println( TextBuffer.toString().trim() );
has no effects on the original string, it just prints the original string.
I want to example the reason why I want to use the split(), it is because I want parse that string and put each substring that ends with "\n" in an array line, here is an example:
my originale string:
(no hi virtual x oy)\n\n house cat \n open it \n\n trying to....
after parsing I would print each line of an array and the output should be:
line 1: (no hi virtual x oy)\
line 2: house cat
line 3: open it
line 4: trying to
and so on.....
If I understood your question correctly I would do something like this
String str = "(no hi virtual x oy)\n\n house cat \n open it \n\n trying to....";
List<String> al = new ArrayList<String>(Arrays.asList(str.toString()
.split("\\n")));
al.removeAll(Arrays.asList("", null)); // remove empty or null string
for (int i = 0; i< al.size(); i++) {
System.out.println("Line " + i + " : " + al.get(i).trim());
}
Output
Line 0 : (no hi virtual x oy)
Line 1 : house cat
Line 2 : open it
Line 3 : trying to....

Categories