Appending to array in Java - java

I have a problem with this code
String[] strLines = null;
while ((strLine = br.readLine()) != null){
strLines = strLine.split("\\s");
System.out.printf("next line - %s\n", strLine);
for(String asd : strLines) {
System.out.printf("array element - %s\n", asd);
}
System.out.println(strLines.length);
}
I'm trying to make a program read from file and then write all unique words into another file. The problem I'm having is that strLines array (which I later convert to Set) is overwritten with every iteration of while loop. Is it possible to somehow append to this array or should I use another way to store my words?
This might be a very beginner question (I've only been coding for a couple of months irregularly), but I couldn't find an answer to it anywhere. Thanks in advance!

There's no reason to create an array if all you do with it is converting it to a set later. Simply add to your set in the while loop:
String foo = "foo bar baz foo bar baz";
Set<String> fooSet = new HashSet<>();
fooSet.addAll(Arrays.asList(foo.split("\\s")));
For your example
Set<String> fooSet = new HashSet<>();
while ((strLine = br.readLine()) != null){
fooSet.addAll(Arrays.asList(strLine.split("\\s")));
}

When you don't know what the exact size of your array might be, I'd use an ArrayList. An ArrayList does need an import given here: import java.util.ArrayList You also need to declare it in a certain way. For an ArrayList full of Strings is this: ArrayList<String> arrayListOfStrings = new ArrayList<String>(); For an ArrayList of type Object would be this: ArrayList<Object> arrayListOfObjects = new ArrayList<Object>(); You can make an ArrayList of any type of object. To add an item you use ArrayList's .add() function. IE: arrayListOfObjects.add(indexOfObject) ArrayLists also have .get(index), .remove(index) .add(index, Object) .size() etc. I hope that you find this brief tutorial on ArrayLists helpful!

You can use a List<String> collection to store all found words in this way:
List<String> words = new ArrayList<>();
while ((strLine = br.readLine()) != null){
String[] strLines = strLine.split("\\s");
words.addAll(Arrays.asList(strLines));
System.out.printf("next line - %s\n", strLine);
}
for(String word: words) {
System.out.printf("word - %s\n", word);
}
System.out.println(words.size());

Thanks a lot for the answers! All of them have been really helpful, solved my issue with creating a set in the while loop, as baao suggested.

Related

how to sort records in csv files using particular column in java

I'm reading student data from csv file and trying to sort data in descending order by using marks column and trying to get top n and last n student records. I'm facing problem how to sort complete csv file by particular column and where to store that sorted data and how to retrieve top n student records.
I tried using the below code to sort marks column. By using that I can sort that column but I can't get remaining fields like name, roll number and phone num.
String splitBy = ",";
String line = "";
ArrayList<String> marks = new ArrayList<>();
BufferedReader br = new BufferedReader(new FileReader("Student_Records.csv"));
while((line = br.readLine()) != null) {
String[] b = line.split(splitBy);
//System.out.println(b[5]+" && "+b[6]);
marks.add(b[7]);
}
List<Integer> newList = marks.stream()
.map(s -> Integer.parseInt(s))
.collect(Collectors.toList());
Collections.sort(newList, Collections.reverseOrder());
for(int i : newList)
System.out.println(i);
You are storing only the marks in the list that you create. You need to store the other data that you want as well.
Instead of using a List<String> and converting to a List<Integer>, you could create a new class, ie: StudentRecord. That class could have fields for the values in your csv, such as a mark field, a name, etc.. Then you can put them into a List<StudentRecord>.
If you do that, your problem becomes "How do I sort a list of objects based on one of their fields?" You can use the Comparator or Comparable interfaces to decide how you want to sort them.
To see many examples of how to use either of those interfaces, you can Google "java comparator examples" or "java comparable examples".
Try this out, this should at least give you a start (I don't have a csv to test it):
//Loading file into a List
String splitBy = ",";
String line="";
List<List<String>> marks = new ArrayList<>();
BufferedReader br = new BufferedReader(new FileReader("Student_Records.csv"));
while((line = br.readLine()) != null){
String[] b = line.split(splitBy);
//System.out.println(b[5]+" && "+b[6]);
marks.add(Arrays.asList(b));
}
//Creating the comparator
Comparator<List<String>> comp = new Comparator<List<String>>() {
public int compare(List<String> marksLine1, List<String> marksLine2) {
return Integer.valueOf(marksLine1.get(7)).compareTo(Integer.valueOf(marksLine2.get(7))); //Change the 7s to the column index you want to sort by (I assume 7 is your marks column)
}
};
//Sorting using the comparator
Collections.sort(marks, comp);
//Printing the sorted csv
for(List<String> i : marks)
System.out.println(i.toString());
//Close the BufferedReader
br.close();
I used List instead of just ArrayList so that it can hold the entire csv data. ArrayList is only capable of holding a single line unless you wrap it in another list. Basically the first list holds the data horizontally, then you need the 2nd list wrapped to hold the data vertically.
Additionally I created a custom comparator where you can edit to sort it according to what you need. You also may need to throw or catch an IOException if you try this out.

Java- Add each word to an arraylist?

this may be pretty simple, but for some reason I am blanking right now.
Suppose I had a string "Hello I Like Sports"
How would I add each word to an arraylist (so each word is in an index in the arraylist)?
Thanks in advance!
ArrayList<String> wordArrayList = new ArrayList<String>();
for(String word : "Hello I like Sports".split(" ")) {
wordArrayList.add(word);
}
The first thing to do is to split that sentence up into pieces. The way to do that is to use String.split That will return an Array of Strings.
Since you want it in an ArrayList, the next thing you have to do is loop through every String in the array and add it to an ArrayList
String[] words = sentence.split(" ");
list.addAll(Arrays.asList(words));
Try this:
public static void main(String[] args) {
String stri="Hello I Like Sports";
String strar[]=stri.split(" ");
ArrayList<String> arr = new ArrayList<String>(Arrays.asList(strar));
for(int x=0;x<arr.size();x++){
System.out.println("Data :"+arr.get(x));
}
}
Output :
Data :Hello
Data :I
Data :Like
Data :Sports
you can use the split method of the String and split on spaces to get each word in a String array. You can then use that array to create an arrayList
String sentence ="Hello I Like Sports";
String [] words = sentence.split(" ");
ArrayList<String> wordList = new ArrayList<String>(Arrays.asList(words));
String.split()
Arrays.asList()
A little search would have done the work.
Still I am giving a solution to this. You can use Split.
You can later add those array elements to arraylist if you require.
String s="Hello I like Sports";
String[] words = s.split(" "); //getting into array
//adding array elements to arraylist using enhanced for loop
List<String> wordList=new ArrayList();
for(String str:words)
{
wordList.add(str);
}
First, you have to split the string, and :
if you want a List, use Arrays.asList
if you want an ArrayList, create one from this List.
Sample code :
final String str = "Hello I Like Sports";
// Create a List
final List<String> list = Arrays.asList(str.split(" "));
// Create an ArrayList
final ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(str.split(" ")));
Using Arrays.asList and the ArrayList constructor avoids you to iterate on each element of the list manually.
try this code was perfect work for get all word from .txt file
reader = new BufferedReader(
new InputStreamReader(getAssets().open("inputNews.txt")));
// do reading, usually loop until end of file reading
String mLine;
while ((mLine = reader.readLine()) != null) {
for(String word :mLine.split(" ")) {
lst.add(word);
}
}

Buffer string to array list, and split

I am buffering a text file of into 'arraylist lines' i then need to split each line into a new arrayList parts, so that i can find information from each line and add the data to a model i have built, the reason i am using arrayLists is because of there expandable properties, meaning i wont need to worry about the size of either the line or the text file.
the code is below:
try(BufferedReader buffer =
new BufferedReader(new FileReader("src/Sample.txt")))
{
String currentLine;
ArrayList<String> lines = new ArrayList<String>();
ArrayList<String> parts = new ArrayList<String>();
//ListIterator<String> lineItr = lines.listIterator();
while((currentLine = buffer.readLine()) != null)
{
lines.add(currentLine);
for(String line : lines)
{
parts.addAll(line.split("\\s+"));
}
//lineItr.next();
//lineItr.set(currentLine);
//System.out.println(lineItr.next());
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
i am having my troubles with parts.addAll(line.split("\s+");
i do not understand why the statement does not iterate through lines, splitting and adding each part of the string to the parts array list, am i misunderstanding something here?
thanks Babble
list.addAll() accepts a java.util.Collection where as str.split returns you an array is not a collection. Hence you can not add it directly to a list. You need to convert into a list first.
for(String line : lines)
{
parts.addAll(Arrays.asList(line.split("\\s+"));
}
String.split() returns Array of String . So you have to use Arrays.asList() to convert it into list .
parts.addAll(line.split("\\s+"));
Above line should be:
parts.addAll(Arrays.asList(line.split("\\s+")));
Or :
Collections.addAll(parts, line.split("\\s+"));
try this
parts.addAll(Arrays.asList(line.split("\\s+")));
List.addAll accepts a Collection but line.split("\\s+") returns String[]. You can do it this way
parts.addAll(Arrays.asList(line.split("\\s+")));
Every time a new line arrives, you append the whole thing all over again. Drop the inner "for" loop, and just split currentLine instead.
EDIT based on comment:
The Java Way would be implementing the year and month objects as containers. The simpler alternative is using string-keyed maps.

Java: deepcopy list entry without instancing a new list

I've got a little problem while doing my programming task. I want to read some lines from a file (no problem so far) and tokenize it. Every line has about 4 tokens and each of them should find a place in a list. In the end, every line should be in a list too.
A little example to clarify this:
File Content:
foo boo barbii buu baa
output:
[[foo, boo, bar], [bii, buu, baa]]
And heres the code I'm dealing with
String fileContent = fileloader(file.toString());
List<String> linesList = new ArrayList<String>();
String[] lines = fileContent.split("\n");
for(String line:lines){
String[] splittedLine = line.split("\t");
for(String words:splittedLine){
linesList.add(words);
}
lexiconContent.add(linesList);
linesList.removeAll(linesList);
}
I guess there's a problem with the references, because the first iteration works well! But in the second iteration, it copies the actual second content also to the first (0) list position and so on.
Finally I got something like [[], [], [], []]
The problem is that, you have created only one list, and adding a reference to that list to your outer list, by modifying it on each iteration. So, the final modification done to that list will be reflected for all the references.
You can solve this problem by creating a new linesList each time in the loop: -
List<String> linesList = null; // Don't initialize here
String[] lines = fileContent.split("\n");
for(String line:lines){
String[] splittedLine = line.split("\t");
linesList = new ArrayList<String>(); // Initialize a new list everytime.
for(String words:splittedLine){
linesList.add(words);
}
lexiconContent.add(linesList);
}
And yes, you can also simplify your for loop to: -
for(String line:lines){
String[] splittedLine = line.split("\t");
lexiconContent.add(new ArrayList<String>(Arrays.asList(splittedLine)));
}
This way, you don't have to iterate over your array, and add individual elements to your List. In fact, you don't need an intermediate list at all.
In your code..Instead of creating new ArrayList for each iteration in loop: for(String line:lines) You are just adding the words (in nested loop) in the old object of ArrayList that you had used right from the first iteration of outer loop and storing that same reference value at all subsequent index of lexiconContent ArrayList.Also at the end of each iteration of outer loop you are clearing the linesList .So Finally you are remained with N number of entries in lexiconContent...Where the Element at each index of lexiconContent is nothing but the reference value of the single object of ArrayList(lineList) which is Empty!!!
You should use following code instead:
String fileContent = fileloader(file.toString());
List<String> linesList = null;
String[] lines = fileContent.split("\n");
for(String line:lines){
List<String> linesList = new ArrayList<String>();
String[] splittedLine = line.split("\t");
for(String words:splittedLine){
linesList.add(words);
}
lexiconContent.add(linesList);
}

What is the best and optimal solution to iterate thought list of array of strings and get its value out?

I have list of array of strings, List <String []>, what is the best optimal approach to get contents of this list of array of strings?
public List<String []> readFromString (String data){
StringReader stringReader = new StringReader(data);
CVSReader reader = new CVSReader(stringReader);
return reader.readAll()
}
In above example, I want to see the actual contain of reader.readAll(), any suggestions as to what is the optimal way to get that information out?
I don't think there's any avoiding looping through the entire structure. Even if you call .toString(), which may well give what you want, you're still going to incur the cost of looping over the entire data structure:
String results = readFromString(data);
StringBuilder output = new StringBuilder();
for(String[] sArray : results) {
for(String s : sArray) {
output.append(s);
}
}
System.out.println(output);
(Note: insert formatting characters as required - you might want to put a comma after each string, and a \n after each list completes, to make the output more readable.)
By wanting to see the content and "get information out", if you mean that you want to send it to standard out, or your log file, to see a full dump of the data, you can use the List toString (i.e. System.out.println(reader.readAll()); ). It prints all values. The following unit test confirms it:
public void testListOfArraysToStringPrintsAllValues(){
String[] array1 = ["array1.1", "array1.2"];
String[] array2 = ["array2.1", "array2.2"];
List<String[]> listOfArrays = new ArrayList<String[]>();
listOfArrays.add(array1);
listOfArrays.add(array2);
assertEquals("[[array1.1, array1.2], [array2.1, array2.2]]", listOfArrays.toString());
}
Are you looking for something like this?
for(String[] sArray : new CVSReader(new StringReader(data)).readAll())
{
for(String s : sArray)
{
System.out.prinntln(s);
}
System.out.prinntln("*********");
}
I can be wrong but my suggetions are:
To separte the lines:
String[] lines = data.split("\n");
To get a java.util.List
java.util.Arrays.asList(lines)
To separate each line:
String[] fields = line.split(",");
where line will be one of the String[] lines element.

Categories

Resources