Input is a String array, Output is an ArrayList - java

My problem consists, that I want to insert a String[] into an ArrayList, this works fine.
Whilst trying to get my String[] from the ArrayList, I only receive an ArrayList in return. Is there any way I can retrieve my String[].
I cannot seem to find the method that could solve this problem. I would like to restrain myself from programming around it.
public ArrayList<String> getAllAttributes() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(vmxConfigFile));
ArrayList<String> attributes = new ArrayList<String>();
for(int i = 0 ; i < getAmountOfAttributes() ; i++) {
String line = reader.readLine();
String[] attribute = line.split("=");
attributes.addAll(Arrays.asList(attribute));
}
return attributes;
}
public static void main(String[] args) throws IOException {
VMXConverter vmx = new VMXConverter("file:///C://Users//trisi//Downloads//vCloud-Availability.vmx_ ");
ArrayList<String> list = vmx.getAllAttributes();
for(int i = 0; i < list.size(); i++) {
// What i want to do: String[] x = list.get(i);
String x = list.get(i); <--this is currently my only option
}
}
I expect, that when I grab the element in my list, it should be an array of size 2, with 2 keywords.
Instead, I get a list in which the Elements are no longer sorted as arrays

It is because you are not adding the Array of Strings to your arraylist, instead you add all elements of the String array to the arraylist, so You'll only get one big arraylist.
What you can do is not return with an arraylist of string, but an arraylist of string array:
public ArrayList<String[]> getAllAttributes() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(vmxConfigFile));
ArrayList<String[]> attributes = new ArrayList<>();
for(int i = 0 ; i < getAmountOfAttributes() ; i++) {
String line = reader.readLine();
String[] attribute = line.split("=");
attributes.add(attribute);
}
return attributes;
}
public static void main(String[] args) throws IOException {
VMXConverter vmx = new VMXConverter("file:///C://Users//trisi//Downloads//vCloud-Availability.vmx_ ");
ArrayList<String[]> list = vmx.getAllAttributes();
for(int i = 0; i < list.size(); i++) {
String[] x = list.get(i);
}
}
However I do not think you want this. If I understand well you have a file containing key=value pairs. I suggest load them into a Map, so it will be much more easier to work with.
You can load to map like this:
public Map<String,String> getAllAttributesMap() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(vmxConfigFile));
Map<String,String> attributes = new HashMap<>();
while( (line = br.readLine()) != null){
String[] attribute = line.split("=");
if(attribute.length>0 && attribute[0]!=null)
attributes.put(attribute[0],attribute.length<1?null:attribute[1]); //just to avoid null pointer problems...
}
return attributes;
}
And so you can easily get a value of a key from the map.
Map<String,String> attributes=getAllAttributesMap();
System.out.println("Value of foo: "+attributes.get("foo"));
System.out.println("Value of bar: "+attributes.get("bar"));

At the moment you have a list of Strings. When you add the String[] to the list each single element of the array will be added separately to the list.
If you want to keep the arrays as they are, then you need to use a list of String[].
public ArrayList<String[]> getAllAttributes() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(vmxConfigFile));
ArrayList<String[]> attributes = new ArrayList<String>();
for(int i = 0 ; i < getAmountOfAttributes() ; i++) {
String line = reader.readLine();
String[] attribute = line.split("=");
attributes.add(attribute);
}
return attributes;
}
public static void main(String[] args) throws IOException {
VMXConverter vmx = new VMXConverter("file:///C://Users//trisi//Downloads//vCloud-Availability.vmx_ ");
ArrayList<String[]> list = vmx.getAllAttributes();
for(int i = 0; i < list.size(); i++) {
String[] x = list.get(i);
}
}

You need ArrayList < String[] > instead ArrayList < String >.
Something like this:
public ArrayList<String[]> getAllAttributes() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(vmxConfigFile));
ArrayList<String[]> attributes = new ArrayList<>();
for(int i = 0 ; i < getAmountOfAttributes() ; i++) {
String line = reader.readLine();
String[] attribute = line.split("=");
attributes.add(attribute);
}
return attributes;
}

Related

Read & split multiple column text file into arrays

For a project I'm working on a fairly big animal dataset with up to 14 parameters of data. I was able to read it in and display it as strings using this:
public static void readIn(String file) throws IOException {
Scanner scanner = new Scanner(new File(file));
while (scanner.hasNext()) {
String[] columns = scanner.nextLine().split("/t");
String data = columns[columns.length-1];
System.out.println(data);
}
}
and displaying something like this:
04:00:01 0.11 0.04 -0.1 1047470 977.91 91.75
04:00:01 0.32 -0.03 -0.07 1047505 977.34 92.91
04:00:01 0.49 -0.03 -0.08 1047493 978.66 92.17
But I'm currently having trouble trying to split each column into separate arrays so that I can process the data (e.g. calculating means). Any idea of how I can do this? Any help would be much appreciated.
Edit: thanks, I've found out a solution that works and also lets me choose which channel it reads specifically. I've also decided to store the data as arrays within the class, here's what I have now:
public static void readChannel(String file, int channel) throws IOException
{
List<Double> dataArr = new ArrayList<>();
Scanner scanner = new Scanner(new File(file));
while (scanner.hasNext()) {
String[] columns = scanner.nextLine().split("\t");
for (int i = channel; i < columns.length; i+=(columns.length-channel)) {
dataArr.add(Double.parseDouble(columns[i]));
dataArr.toArray();
}
}
}
You can store all rows in an ArrayList and then create arrays for each column and store values in them. Sample code:
Scanner scanner = new Scanner(new File(file));
ArrayList<String> animalData = new ArrayList<String>();
while (scanner.hasNext()) {
String[] columns = scanner.nextLine().split("/t");
String data = columns[columns.length-1];
animalData.add(data);
System.out.println(data);
}
int size = animalData.size();
String[] arr1 = new String[size]; String[] arr2 = new String[size];
String[] arr3 = new String[size]; String[] arr4 = new String[size];
for(int i=0;i<size;i++)
{
String[] temp = animalData.get(i).split("\t");
arr1[i] = temp[0];
arr2[i] = temp[1];
arr3[i] = temp[2];
arr4[i] = temp[3];
}
I think you should split your problem in 2:
File reading:
Your program read each line and save it inside a instance of a class defined by you:
public class MyData {
private String time;
private double percent;
//... and so on
}
public MyData readLine( String line ) {
String[] columns = line.split("\t");
MyData md = new MyData();
md.setTime( columns[ 0 ] );
md.setPercent( Double.parseDouble(columns[ 1 ]) );
}
public void readFile( File file ) {
Scanner scanner = new Scanner(file);
List<MyData> myList = new ArrayList<>();
while (scanner.hasNext()) {
MyData md = readLine( scanner.nextLine() );
myList.add( md );
}
}
Data processing:
After you processed your file, you can create the method you need to process the data:
int sum = 0;
for ( MyData md : myList ) {
sum = sum + md.getValue();
}
I hope it help.
Following snippet will list down all values for a given index
public static void readIn(String file) throws Exception {
Scanner scanner = new Scanner(new File(file));
final Map<Integer,List<String>> resultMap = new HashMap<>();
while (scanner.hasNext()) {
String[] columns = scanner.nextLine().split("/t");
for(int i=0;i<columns.length;i++){
resultMap.computeIfAbsent(i, k -> new ArrayList<>()).add(columns[i]);
}
} resultMap.keySet().forEach(index -> System.out.println(resultMap.get(index).toString()));}

Compare 2 *.txt files and print difference between them

I have a problem wrtting the code for comparing two files (first reference file):
PROTOCOL STATE SERVICE
1 open icmp
6 open tcp
17 open udp
and (execution file)
PROTOCOL STATE SERVICE
1 open icmp
6 open tcp
17 open udp
255 closed unknown
and save difference between these two files in new file (255 closed unknown).
For comparing I have used following code but it seems it doesn't work.
public String[] compareResultsAndDecide(String refFile, String execFile) throws IOException {
String[] referenceFile = parseFileToStringArray(refFile);
String[] execCommand = parseFileToStringArray(execFile);
List<String> tempList = new ArrayList<String>();
for(int i = 1; i < execCommand.length ; i++)
{
boolean foundString = false; // To be able to track if the string was found in both arrays
for(int j = 1; j < referenceFile.length; j++)
{
if(referenceFile[j].equals(execCommand[i]))
{
foundString = true;
break; // If it exist in both arrays there is no need to look further
}
}
if(!foundString) // If the same is not found in both..
tempList.add(execCommand[i]); // .. add to temporary list
}
String diff[] = tempList.toArray(new String[0]);
if(diff != null) {
return diff;
}
For String refFile I would use /home/xxx/Ref.txt path to reference file. And the same for execFile (second file shown up).
Anyone can help me with this?
Just to add, I'm using for parsing File to String Array:
public String[] parseFileToStringArray(String filename) throws FileNotFoundException {
Scanner sc = new Scanner(new File(filename));
List<String> lines = new ArrayList<String>();
while (sc.hasNextLine()) {
lines.add(sc.nextLine());
}
String[] arr = lines.toArray(new String[0]);
return arr;
}
Change int i = 1 to int i = 0 and int j = 1 to int j = 0
your compareResultsAndDecide method has to be changed like :
public static String[] compareResultsAndDecide(String refFile, String execFile) throws IOException {
String[] referenceFile = parseFileToStringArray(refFile);
String[] execCommand = parseFileToStringArray(execFile);
List<String> tempList = new ArrayList<String>();
List<String> diff = new ArrayList(Arrays.asList(execCommand));
diff.removeAll(Arrays.asList(referenceFile));
String[] toReturn = new String[diff.size()];
toReturn = diff.toArray(toReturn);
return toReturn;
}
and your parseFileToStringArray like:
public String[] parseFileToStringArray(String filename) throws FileNotFoundException {
Scanner sc = new Scanner(new File(filename));
List<String> lines = new ArrayList<String>();
while (sc.hasNextLine()) {
lines.add(sc.nextLine());
}
String[] arr = new String[lines.size()];
return lines.toArray(arr);
}
Problem is in your .txt files. Your encoding must be different.
I know this isn't the best way, but if you use replaceAll() method to replace white spaces from your lines of text files, your code should work. But Unfortunately, you will miss the spaces between lines.
Change:
String[] arr = lines.toArray(new String[0]);
To:
String[] arr = lines.toArray(new String[0]).replaceAll(" ", "");
Note:
I tried using trim() but it didn't worked well for me.
As I mentioned above, array elements starts from 0, not from 1. Change that too.

How to save integers from a .txt file into an array?

So i have an array int[] numbers = {1,2};
But i want the 1,2 to be removed and replaced with numbers from an txt file.
I can see the numbers from the files in the console with this method:
public String[] readLines(String filename) throws IOException {
FileReader fileReader = new FileReader(filename);
BufferedReader bufferedReader = new BufferedReader(fileReader);
List<String> lines = new ArrayList<String>();
String line = null;
while ((line = bufferedReader.readLine()) != null) {
lines.add(line);
}
bufferedReader.close();
return lines.toArray(new String[lines.size()]);
}
public static void testFileArrayProvider() throws IOException {
algo1 fap = new algo1();
String[] lines = fap
.readLines("D:/Users/XXX/workspace/abc/src/abc1/Filename123");
for (String line : lines) {
System.out.println(line);
}
}
NOw i need to save them in the array. BUt how? xd
Thx guys
This should work:
// In your case this is already populated
String[] lines = new String[] {"123", "4567"};
// Easier to work with lists first
List<Integer> results = new ArrayList<>();
for (String line : lines) {
results.add(Integer.parseInt(line));
}
// If you really want it to be int[] for some reason
int[] finalResults = new int[results.size()];
for (int i = 0; i < results.size(); i++) {
finalResults[i] = results.get(i);
}
// This is only to prove it worked
System.out.println(Arrays.toString(finalResults));
In Java-8, you can shorten it to
int[] finalResults = Arrays.stream(lines).mapToInt(Integer::parseInt).toArray();

How can I read only one thing in from a textfile?

I can read in from the file and am able to change the amount of lines given by changing the number in the for loop but I don't want all the numbers in my file displayed side by side like that. I need them all going down one by one randomly.
public class Assignment2 {
public static void main(String[] args) throws IOException
{
// Read in the file into a list of strings
BufferedReader reader = new BufferedReader(new FileReader("textfile.txt"));
List<String> lines = new ArrayList<String>();
String line = reader.readLine();
while( line != null ) {
lines.add(line);
line = reader.readLine();
}
// Choose a random one from the list
Random r = new Random();
for (int p = 0; p<3; p++)
{
String randomString = lines.get(r.nextInt(2));
System.out.println(lines);
}
}
}
I think what you want to print is
String randomString = lines.get(r.nextInt(2));
System.out.println(randomString);
To display only the first 20 random lines from this list of maybe 100
for (int i = 0; i < 20; i++) {
int rowNum = r.nextInt(lines.size ());
System.out.println(lines.get(rowNum);
}

Reading CSV file without third-party libraries

I'm trying to read a csv file into either an ArrayList or a String [][] array. In this I'm trying to read it into a list and then form the list, using a tokenizer, into an array. The csv file have 7 columns (A - G) and 961 rows (1-961). My for loop for the 2D array keeps returning a null pointer, but I think it should be working..
public class FoodFacts
{
private static BufferedReader textIn;
private static BufferedReader foodFacts;
static int numberOfLines = 0;
static String [][] foodArray;
public static String aFact;
static int NUM_COL = 7;
static int NUM_ROW = 961;
// Make a random number to pull a line
static Random r = new Random();
public static void main(String[] args)
{
try
{
textIn = new BufferedReader(new InputStreamReader(System.in));
foodFacts= new BufferedReader(new FileReader("foodfacts.csv"));
Scanner factFile = new Scanner(foodFacts);
List<String> facts = new ArrayList<String>();
String fact;
System.out.println("Please type in the food you wish to know about.");
String request = textIn.readLine();
while ( factFile.hasNextLine()){
fact = factFile.nextLine();
StringTokenizer st2 = new StringTokenizer(fact, ",");
//facts.add(fact);
numberOfLines++;
while (st2.hasMoreElements()){
for ( int j = 0; j < NUM_COL ; j++) {
for (int i = 0; i < NUM_ROW ; i++){
foodArray [j][i]= st2.nextToken(); //NULL POINTER HERE
System.out.println(foodArray[j][i]);
}
}
}
}
}
catch (IOException e)
{
System.out.println ("Error, problem reading text file!");
e.printStackTrace();
}
}
}
Initialize your foodArray as foodArray = new String[NUM_ROW][NUM_COL]; before using it.
Also, there is no need for inner for loop as you are reading one row at a time.
use numberOfLines as row:
while ( factFile.hasNextLine() && numberOfLines < NUM_ROW){
fact = input.nextLine();
StringTokenizer st2 = new StringTokenizer(fact, ",") ;
//facts.add(fact);
while (st2.hasMoreElements()){
for ( int j = 0; j < NUM_COL ; j++) {
foodArray [numberOfLines][j]= st2.nextToken();
System.out.println(foodArray[numberOfLines][i]);
}
}
numberOfLines++;
}
Alternatively, I think you can use split to get all columns as once e.g.
while ( factFile.hasNextLine() && numberOfLines < NUM_ROW){
fact = input.nextLine();
foodArray [numberOfLines++] = fact.split(",");
}
One question: Is there any specific purpose for declaring all variables as static class variables? Most of them fit as local variable inside the method e.g. numberOfLines?
You can use this String [][] foodArray = csvreadString(filename); method. It actually reads the file twice, but I don't know how to get the csv dimension without reading the data (you need the dimension in order to initialize the array), and this is very fast in comparison to other methods that I tried.
static public class PairInt {
int rows = 0;
int columns = 0;
}
static PairInt getCsvSize(String filename) throws Throwable {
PairInt csvSize = new PairInt();
BufferedReader reader = new BufferedReader(new FileReader(new File(filename)));
String line;
while ((line = reader.readLine()) != null) {
if (csvSize.columns == 0) {
csvSize.columns = line.split(",").length;
}
csvSize.rows++;
}
reader.close();
return csvSize;
}
static String[][] csvreadString(String filename) throws Throwable {
PairInt csvSize = getCsvSize(filename);
String[][] data = new String[csvSize.rows][csvSize.columns];
BufferedReader reader = new BufferedReader(new FileReader(new File(filename)));
for (int i = 0; i < csvSize.rows; i++) {
data[i] = reader.readLine().split(",");
}
return data;
}

Categories