Is there a cap on the number of entry in a ConcurrentHashMap? - java

I am working to read a file of about 2 million entries. Not all are valid lines, but that's the cap. I am using a Map to store key value pairings from the file. I however find that the last term is at line 1932513. I am coding with eclipse, in Java, and went over to bump up the Xmx parameters in the eclipse.ini. This did not solve the problem. Here is the code I am working with:
BufferedReader bufferedRead = new BufferedReader(inputStream);
String data;
try {
while((data = bufferedRead.readLine()) != null) {
String[] meterReadings = data.split(";");
if("Date".equals(meterReadings[0])) continue;
/*
* Creating the key object using concatenation of date-time
*/
if(newApp.isEmpty(meterReadings)) continue;
List<Object> valueList = new ArrayList<Object>();
String[] subDate = meterReadings[0].split("/");
StringBuffer dateTime = new StringBuffer();
for(String s : subDate) {
dateTime.append(s + ":");
}
dateTime.append(meterReadings[1]);
for(int i=2; i < meterReadings.length -1; ++i) {
valueList.add(meterReadings[i]);
}
newApp.textMap.put(dateTime.toString(), valueList);
}
} catch (IOException e) {
log.error("Unable to read from file: ", App.DATA_DIR + App.FILENAME);
e.printStackTrace();
}
/*
* Checking to see if Map has been created
*/
System.out.println("*****************************************");
Set<String> newSet = newApp.textMap.keySet();
Object[] setArray = newSet.toArray();
System.out.println("The last term's key is : " + (String) setArray[setArray.length - 1]);
System.out.println(newApp.textMap.size());
log.info("The size of the reading is : ", newApp.textMap.size());
System.out.println("*****************************************");
}

Related

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;
});
}

Split information in a CSV file using Java, count the strings and discard the duplicates

I have a CSV file with the following information:
2,Cars
5,Cars
5,Planes
5,Boats
10,Planes
10,Boats
28,Planes
I want to split the numbers from the type of transportation. How can I count the total of cars + planes + boats to be '3' and not '7'?
I am using the following Java code that someone else provided to split the CSV:
try {
BufferedReader br2 = new BufferedReader(new FileReader("transport.csv"));
System.out.println("\nTESTING");
String sCurrentLine2;
java.util.HashMap<String, String>();
while ((sCurrentLine2 = br2.readLine()) != null) {
String[] information2 = sCurrentLine2.split(",");
String transCode = information2[1];
System.out.println(transCode);
}
} catch (IOException e) {
e.printStackTrace();
}
In the array String transCode = information2[1]; when I change to 0 it will give the numbers, when I change to 1 gives the names.
while((sCurrentLine2 = br2.readLine()) != null{
String[] entries = sCurrentLine2.split(",");
Set<String> types = new Hashset<>();
for(int i = 0; i < entries.length; i++){
String[] entry = entries[i].split(" ");
types.add(entry[0]);
}
System.out.println(types.size());
}
I modified the code you provided. Maybe there is another way to do it better, but this is what I did. I forced it a little and gave '3' as result. But it should have done it counting the words not considering duplicated.
while ((line2 = br2.readLine()) != null) {
String[] entries = line2.split(",");
for (int i = 0; i < entries.length; i++) {
String[] entry = entries[i].split(" ");
termsDup.add(entry[0]);
}
}
System.out.println(termsDup.size()-4);

Make an array of words in alphabetical order in java, after reading them from a file

I've got the following code that opens and read a file and separates it to words.
My problem is at making an array of these words in alphabetical order.
import java.io.*;
class MyMain {
public static void main(String[] args) throws IOException {
File file = new File("C:\\Kennedy.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = null;
int line_count=0;
int byte_count;
int total_byte_count=0;
int fromIndex;
while( (line = br.readLine())!= null ){
line_count++;
fromIndex=0;
String [] tokens = line.split(",\\s+|\\s*\\\"\\s*|\\s+|\\.\\s*|\\s*\\:\\s*");
String line_rest=line;
for (int i=1; i <= tokens.length; i++) {
byte_count = line_rest.indexOf(tokens[i-1]);
//if ( tokens[i-1].length() != 0)
//System.out.println("\n(line:" + line_count + ", word:" + i + ", start_byte:" + (total_byte_count + fromIndex) + "' word_length:" + tokens[i-1].length() + ") = " + tokens[i-1]);
fromIndex = fromIndex + byte_count + 1 + tokens[i-1].length();
if (fromIndex < line.length())
line_rest = line.substring(fromIndex);
}
total_byte_count += fromIndex;
}
}
}
I would read the File with a Scanner1 (and I would prefer the File(String,String) constructor to provide the parent folder). And, you should remember to close your resources explicitly in a finally block or you might use a try-with-resources statement. Finally, for sorting you can store your words in a TreeSet in which the elements are ordered using their natural ordering2. Something like,
File file = new File("C:/", "Kennedy.txt");
try (Scanner scanner = new Scanner(file)) {
Set<String> words = new TreeSet<>();
int line_count = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
line_count++;
String[] tokens = line.split(",\\s+|\\s*\\\"\\s*|\\s+|\\.\\s*|\\s*\\:\\s*");
Stream.of(tokens).forEach(word -> words.add(word));
}
System.out.printf("The file contains %d lines, and in alphabetical order [%s]%n",
line_count, words);
} catch (Exception e) {
e.printStackTrace();
}
1Mainly because it requires less code.
2or by a Comparator provided at set creation time
If you are storing the tokens in a String Array, use Arrays.sort() and get a naturally sorted Array. In this case as its String, you will get a sorted array of tokens.

Java - NumberFormatException at linear search

I am having this issue with the NumberFormatException in my program. Basically, I am asked to read a .csv file separated by ; and it looks like this:
// Column Explanation (not in .csv file)
id; Summary; Number; Employee1; Employee2; ....... Employee7;
"1";"Sony";"1600";"Markos";"Nikos";"Antonis";"Nikolas";"Vaggelis";"Markos";"Thanasis";
"2";"HP";"1000";"Marios";"Dimitra";"Nikolia";"Spiros";"Thomas";"Kostas";"Manolis";
"3";"Dell";"1100";"Antonis";"Aggelos";"Baggelis";"Nikos";"Kuriakos";"Panagiotis";"Rafail";
"4";"Acer";"2000";"Marina";"Aggelos";"Spiros";"Marinos";"Xristos";"Antreas";"Basilis";
What I have already done is create a String 2-d array or the .csv file called temp_arr and I am asked to write a method that will run a linear search by id and return that company. So here is the thing.
At first, I thought I should convert the input key from int -> String since my temp_arr is a String and compares the strings (which at that time they would be int but read as Strings) using temp_arr[value][value2].equals(string_key). But I had a NullPointerException.
Then I thought I should better convert my Id's from the temp_arr from String -> Int and then compare with the integer key using == operand. This action returned me a NumberFormatException.
The process is this:
System.out.println("Enter id :");
Scanner input = new Scanner(System.in);
int item = input.nextInt(); // read the key which is an Integer
int id_int; // temp_arr is String and item is int, must convert ids from String -> int
for (int i = 0; i < temp_arr.length; i++)
{
id_int = Integer.parseInt(temp_arr[i][0]); // Convert from String to int
if (id_int == item) // If the Array's Id's are == item
{
System.out.println(item+" is present at location " + (i+1) );
break;
}
if (i == temp_arr.length)
System.out.println(item + " does not exist");
}
My error appears at line 7 and I do not know why.
Read File process:
String csvFile = "sam.csv"; // .csv file to be placed in the project file!
BufferedReader br = null; // ini
String line = "",cvsSplitBy = ";"; // columns asked to be split by ";"
String[] arr = null;
String[][] temp_arr = new String[1000][10];
int temp = 0;
try
{
br = new BufferedReader(new FileReader(csvFile)); //start reading the file
while ((line = br.readLine()) != null) // while the line has words
{
arr = line.split(cvsSplitBy); // creating the array
System.out.println(arr[0] + "\t" + arr[1] + "\t" + arr[2] + "\t" + arr[3] + "\t" + arr[4] + "\t" + arr[5] + "\t" + arr[6] + "\t" + arr[7] + "\t" + arr[8] + "\t" + arr[9] );
for (int i = 0; i<=9; i++)
{
temp_arr[temp][i] = arr[i]; // temp_arr represents (is a copy of) the .csv file
}
temp++;
}
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} finally
{
if (br != null)
{
try
{
br.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
System.out.println("Done!\n");
Output (Image) :
Line 106 which is causing the issue is :
id_int = Integer.parseInt(temp_arr[i][0]); // Convert from String to int
Your issue is that your Integer.parseInt() is trying to parse a "2" WITH QUOTATION MARKS. That's the problem.
A quick solution would be to replace this line:
temp_arr[temp][i] = arr[i];
To this:
temp_arr[temp][i] = arr[i].replaceAll("\"", "");
Anyway, I'd like to suggest using a different data structure for your case, because I've done something like this before for a client. Have you ever heard of HashMaps? You can do something like a HashMap with an int key and String[] values to store your data in, and the key can be your id_int. Maybe you can try this implementation next time. It's a lot more elegant.
Hope I was able to help!
Cheers,
Justin
Would help if you also posted some of your data file and how you are reading it in.
But, my guess from what is presented is if you add System.out.println(temp_arr[i][0]) prior to the 7th line or run this code through a debugger you will see that temp_arr[i][0] is not an integer value as that is what the error is telling you.

Adding list to a list of lists doesn't work

I can not get this code to work.
The .txt file that it is reading from is here:
urls.txt
The problem with this code is that it does not at all add any lines.
Whenever i try to get anything at all from "lists" it gives me an IndexOutOfBoundsException.
The code gets executed each 30 seconds, so i have to call the lists.clear(); method.
NOTE: "lists" is defined earlier:
public static ArrayList<ArrayList<String>> lists = new ArrayList<ArrayList<String>>();
This is my code:
try {
URL urls = new URL("https://dl.dropboxusercontent.com/u/22001728/server%20creator/urls.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(urls.openStream()));
lists.clear();
String line;
ArrayList<String> list = new ArrayList<String>();
lists.add(list);
int y = 0, z = 0;
while ((line = br.readLine()) != null) {
y++;
if(line.equalsIgnoreCase(">")) {
System.out.print("Received command: INSERT ");
lists.add(list);
list.clear();
z++;
System.out.print(" ; Jumping to " + z + "\n");
} else {
System.out.println("Line: " + line + " added to lists[" + z + "].");
lists.get(z).add(line);
}
}
int selectedIndex = comboModel0.getIndexOf(comboModel0.getSelectedItem());
comboModel0.removeAllElements();
System.out.println("\n\n\n");
System.out.println(lists.get(1).get(1));
System.out.println("\n\n\n");
} catch (IOException e) {
System.out.println("Failed to download URLS data.");
}
You are adding a list to your collection of lists, then clearing it. That will clear your local variable, plus the list in your collection.
lists.add(list);
list.clear();
You need to create a copy of that list to add to your collection.
lists.add(new ArrayList<String>(list));

Categories