i have heavy .txt file. it contains a format Like this:
0 1 2 3 4 5 6 7 ... n
0 A, B, c, D, E, F, G, H,
1 AA, BB, CC, DD, EE, FF, GG, HH,
2
3
.
.
n
i want to save each row in Map.
for example in first row: map<0,A> . map<1,B>, Map<2,C>,...
then i want to save this maps in List. for example i want to save 100 rows in List.
for example if i write this function: "" list.get(1).get(4); "" i recived "EE"
it means first i have to go in 1 row, then i go to 4 and recive "EE".
could you please guidance me how to solve this problem?
i read some article about "spring batch" .and it related what i want
could you please help me how can i fix this problem?
public class spliter {
static int w=0;
private static HashMap<Integer,String> map = new HashMap<Integer,String>();
private static List<Map<Integer, String>> list=new ArrayList<Map<Integer,String>>();
public static void main(String[] args) throws IOException{
String string = null;
try {
BufferedReader reader = new BufferedReader(new FileReader("C:\\test.txt"));
while( (string = reader.readLine()) != null ) {
String[] parts = string.split(",");
int i=parts.length;
for(int j=0; j<i; j++){
map.put(j, parts[j]);
}
list.add(map);
w++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
Something this simple can be solved using a Scanner to read each line and then String.split(...) to split each line. Something like:
while line exists
read line into String using Scanner
split String using String#split(...)
use array from split to create a list
add above list to master list
end while
Note that you can contain this in a list of lists, without the need of a Map, at all. List<List<String>> should do it for you.
I think that it would be more instructive to you for us to give you general advice like this, and then to see what you can do with it.
I have made into a Community Wiki, so all might contribute easily to this answer and so no-one will get reputation for up-votes.
I needed the same, i did it with yours in mind
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
public class Spliter {
private static List<Map<String, Object>> list = new ArrayList<> ();
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\829784\\Desktop\\Repo\\Documentacion Repositorio\\test.txt"));
String line = "";
String firstline = reader.readLine();
while ((line = reader.readLine()) != null) {
Map < String, Object > map = new TreeMap < > ();
String[] partsfirstline = firstline.split(";");
String[] parts = line.split(";");
int i = parts.length;
for (int j = 0; j < i; j++) {
map.put(partsfirstline[j], parts[j]);
}
list.add(map);
}
System.out.println(list.get(0).values());
System.out.println(list.get(1).values());
}
}
you could us something like this
public class ArrayReader {
public static void main(String[] args) {
List<List<String >> array = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"));){
String line;
while ((line=br.readLine())!=null)
array.add(Arrays.asList(line.split(",")));
} catch (IOException e) {
e.printStackTrace();
}
}
}
Related
at the beginning I read the file and used split() method and stored each value in 1d array. i must store index 0 and 1 in a string value ans index 2,3 and 4 must be stored in 1d array because "supervisor" object arguments contains two string values(name and id) and 1d array (interests) the problem is at row 0 there is an extra interest (3 interests) and at row 1 and 2 there are two interests.
what i thought about is to store the interests in an arraylist (because the size is not static )and convert it back to 1d array but it did not work
tries to store the interests in 2d array and convert t back to 1d array but it did not work , while splitting the file i splitted (, and #) but i noticed at the end of every interest there is a #
so i kept the # and thought if i can do an if condition while reading the file. is there any simple idea to avoid the error?
the file supervisor.txt contains:
00023, Dr. Haneen, artificial intelligent, data mining, pattern recognition#
00013, Dr. Manar, database, network#
00011, Dr. Hajar, software engineering, games#
Code
public static void main(String[] args)throws Exception {
File supervisorFile=new File("supervisor.txt");
if (!supervisorFile.exists()) {
System.out.println("Sorry the file is not found!"); //checks if the file exists if no it terminates the program
System.exit(0);
}
supervisor sup=null;
String[]supArray=null;
Scanner supRead=new Scanner(supervisorFile);//read supervisor file
while (supRead.hasNext()) {
supArray=supRead.nextLine().split(",");
sup=addSupervisor(supArray);
//System.out.println(sup.toString());
}
}
public static supervisor addSupervisor(String[]arr){
String id=arr[0];
String name=arr[1];
String[] interest=new String[3];
for (int i = 0; i < interest.length; i++) { //here i tried to store all the interests
interest[i]=arr[2]+arr[3]+arr[4];
}//it prints artificial intelligent data mining pattern recognition# and then an indexOutOfBoundsException
return new supervisor(id,name,interest);
}
The solution is to use split with a limit parameter.
class Supervisor{
final String id;
final String name;
String[] fields;
Supervisor(String id, String name, String[] fields) {
this.id = id;
this.name = name;
this.fields = fields;
}
}
Path path = Paths.get("supervisor.txt");
List<Supervisor> supervisors = Files.lines(path, Charset.defaultCharset())
.filter(l -> l.endsWith("#"))
.map(l -> l.substring(0, l.length() - 1)) // Remove #
.map(l -> l.split(",\\s*", 3)) // "00013", "Dr. Manar", "database, network"
.filter(w -> w.length == 3)
.map(w -> new Supervisor(w[0], w[1], w[2].split(",\s*")))
.collect(Collectors.toList());
Use split & ArraysList
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import lombok.AllArgsConstructor;
#AllArgsConstructor
class Supervisor {
String id;
String name;
List<String> interest;
#Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.NO_CLASS_NAME_STYLE);
}
}
public class AMain {
public static void main(String[] args) {
String id, name, line;
String[] arr;
List<String> list = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader("file/supervisor.txt"))) {
while ((line = br.readLine()) != null) {
arr = line.trim().split(",");
list.addAll(Arrays.asList(arr));
if (list.size() > 2) {
id = list.get(0); // get id
list.remove(0); // remove id
name = list.get(0); // get name
list.remove(0); // remove name
System.out.println(new Supervisor(id, name, list));
}
list.clear(); // clear all
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output
[id=00023,name= Dr. Haneen,interest=[ artificial intelligent, data mining, pattern recognition#]]
[id=00013,name= Dr. Manar,interest=[ database, network#]]
[id=00011,name= Dr. Hajar,interest=[ software engineering, games#]]
Your second and third line only has 4 Strings split up by a comma. That makes it 4 Strings in the Array. In your addSupervisor methode you are trying to access arr[4], the 5th String, which is out of bound.
You get an error because you are trying to use arr[4], but wioth the lines 2 and 3 the size of the array will be 4, so the maximum index you can use is 3.
I don't know for sue what Supervisor is, but would this work:
public static supervisoraddSupervisor(String[]arr){
String id=arr[0];
String name=arr[1];
String[] interest=new String[arr.length - 2];
for (int i = 0; i < interest.length; i++) {
interest[i]=arr[i + 2];
}
return new supervisor(id,name,interest);
}
Try it online!
First you should get the line and then work with it like you do. The problem is in the loop for where you suppose all the "supervisor" have 3 interests. Also you are storing all the interest in the first pos of the array:
for (int i = 0; i < interest.length; i++) { //here i tried to store all the interests
interest[i]=arr[2]+arr[3]+arr[4];
}
So I think you should use a function like this:
private static String[] extractInterest(String[] line) {
String[] res = new String[line.length - 2]; //There are two index that haven't got interest
for(int i = 0; i<res.length; ++i) {
res[i] = line[i+2].replaceFirst(" ", "").replace("#","");
}
return res;
}
And this is the "main":
public static void main(String[] args) {
File file = new File("Data.txt");
try (Scanner sc = new Scanner(file)) { //Will close the sc automatically
String[] line;
while(sc.hasNext()) {
line = sc.nextLine().split(",");
int id = Integer.parseInt(line[0]);
String name = line[1].replaceFirst(" ",""); //For delete first " "
String[] interest = extractInterest(line);
Supervisor s = new Supervisor(id,name,interest);
System.out.println(s.toString());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
A final advice, Java classes names must begin with uppercase by agreement. So you should change the name of your class "supervisor" to "Supervisor"
I have a file reader that reads the text
(a,b) (b,c) (c,d) (f,g) (c,g) (c,t) (h,i) (j,y)
and displays
a,b
b,c ....
is there a way to use these indexes as arguments for a method I call right after i'm done reading it? so far I seem to only effect the string split while i'm inside my While loop, is there a way to take value a and use it for method like
add.edge("argument0","argument1") where 0 is a, and 1 is b?
Code:
import java.io.*;
class reader{
public static void main(String[] args)throws Exception{
File file = new File("test.txt");
BufferedReader fi = new BufferedReader(new FileReader(file));
String num;
int count = 0;
while ((num = fi.readLine()) !=null) {
String [] add = num.split(" ");
for(int i=0; i<add.length;i++){
String [] add2 =add[i].split("[)(]+");
for (String val: add2){
System.out.println(val);
}
}
}
}
}
i think you are trying to achieve some thing like following :D
i changed your code a little bit i used sub string instead of regular expression
import java.io.*;
class reader{
public static void main(String[] args)throws Exception{
File file = new File("test.txt");
BufferedReader fi = new BufferedReader(new FileReader(file));
String num;
int count = 0;
while ((num = fi.readLine()) !=null) {
String [] add = num.split(" ");
for(int i=0; i<add.length;i++){
String pair = add[i].substring(1, 4);
someFunction(pair.split(","));
}
}
}
public static void someFunction(String[] args)
{
if(args.length > 0)
System.out.println(args[0] + " and " + args[1]);
}
}
If you want to use the result of the split function outside the while loop you need to save the results to a variable that is defined before the while loop. This is because currently the scope of the add2 variable in inside the for loop and thus you will only be able to use it inside the for loop. If you want to save pairs of Strings then I suggest creating a helper class Pair:
class Pair {
private String el1;
private String el2;
public Pair(String el1, String el2) {
this.el1 = el1;
this.el2 = el2;
}
// getters
}
and make a list of pairs defined before the while loop:
List<Pair> pairs = new ArrayList<>();
and in your for loop, add new pairs to the list:
pairs.add(new Pair(add2[0], add[1])));
Then you can access the list elements outside the while loop like so:
for (Pair pair : pairs) {
add.edge(pair.getEl1(), pair.getEl2());
}
The code below is meant to count the number of times the words in list y occur either in a document via FileReader or list x. Eventually I want list y to be an imported document as well, but when I run the code on a document it either gives me a false count or no count at all. What’s going on?
Also the files are form notepad. I'm using windows
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class test {
#SuppressWarnings("resource")
public static void main(String[] args) throws Exception {
don w = new don();
List<Integer> ist = new ArrayList<Integer>();
// List<String> x =Arrays.asList
// ("is","dishonorable","dismal","miserable","horrible","discouraging","distress","anguish","mine","is");
BufferedReader in = new BufferedReader(new FileReader("this one.txt"));
String str;
List<String> list = new ArrayList<String>();
while ((str = in.readLine()) != null) {
list.add(str);
// System.out.println(list);
List<String> y = Arrays.asList("Hello", "the", "string", "is", "mine");
for (String aY : y) {
int count = 0;
for (String aX : list) {
if (aY.contains(aX)) {
count++;
}
}
ist.add(count);
// no need to reset the count
}
int g = ist .stream()
.mapToInt(value -> value)
.sum();
System.out.println(g);
}
}
}
If you want to count, you should... count.
Here, you only check if the string contains a substring.
What you should do instead is roughly the following:
static int count(String line, String word) {
int count = 0;
for (int offset = line.indexOf(word); offset >= 0; offset = line.indexOf(word, offset + 1 + word.length())) {
count++;
}
return count;
}
Now, of course, you probably have to take into account the fact that you're looking for substrings and not words. But then if you already learned that, you might want to use regular expressions to help you further.
The file that my program is reading contains space separated numbers such "59 23 2 84 83", if i am sure that the # "84" occur only 36 times but bitset.cardinality() report 293 times.. please help
static int line_counter = 0;
static TreeMap<String, BitSet> ItemsArray = new TreeMap<String, BitSet>();
public static void main(String[] args) throws IOException {
String[] line;
BufferedReader br = new BufferedReader(new FileReader("abc.txt"));
while (br.ready()) {
line = br.readLine().split(" ");
Arrays.sort(line);
ItemsArray(line);
line_counter++;
}
System.out.println("ItemsArray cardinality = " + ItemsArray.get("84").cardinality() + "\n");
}
private static void ItemsArray(String[] line) {
BitSet temp_bitset = new BitSet();
for (String item : line) {
temp_bitset.clear();
if (ItemsArray.get(item) == null) {
temp_bitset.set(line_counter);
ItemsArray.put(item, temp_bitset);
} else {
temp_bitset = (BitSet) ItemsArray.get(item).clone();
temp_bitset.set(line_counter);
ItemsArray.put(item, temp_bitset);
}
}
}
Your problem is that there is only one BitSet for each line. You then confuse matters by replacing it with one from the map if the number repeats in several lines which therefore may actually be from a different line. You then seem to clear it for no real reason. You then seem to think clone is the solution to all of the above problems.
Here's an idea:
static int line_counter = 0;
static TreeMap<String, BitSet> allBits = new TreeMap<String, BitSet>();
public static void main(String[] args) throws IOException {
String[] line;
BufferedReader br = new BufferedReader(new FileReader("abc.txt"));
while (br.ready()) {
line = br.readLine().split(" ");
Arrays.sort(line);
consumeItems(line);
line_counter++;
}
System.out.println("ItemsArray cardinality = " + allBits.get("84").cardinality() + "\n");
}
private static void consumeItems(String[] line) {
for (String item : line) {
BitSet temp = allBits.get(item);
if (temp == null) {
temp = new BitSet();
allBits.put(item, temp);
}
// Use a bit in the BitSet to indicate that this number appeared in tat line.
temp.set(line_counter);
}
}
Not sure it's what you need but it demonstrates the normal technique for creating/updating map entries.
This is the question from my assignment that I am unsure of:
The class is to contain a public method nextWord(). When a new line is read, use the String method .split("\s+") to create an array of the words that are on the line. Each call to the nextWord() method is to return the next word in the array. When all of the words in the array have been processed, read the next line in the file. The nextWord()method returns the value null when the end of the file is reached.
I have read the file, and stored each individual string in an array called tokenz.
I'm not sure how I can have a method called "nextWord" which returns each individual word from tokenz one at a time. Maybe I don't understand the question?
The last part of the question is:
In your main class, write a method named processWords() which instantiates the MyReader class (using the String "A2Q2in.txt"). Then write a loop that obtains one word at a time from the MyReader class using the nextWord() method and prints each word on a new line.
I've thought of ways to do this but I'm not sure how to return each word from the nextWord method i'm supposed to write. I can't increase a count because after the String is returned, anything after the return statement cannot be reached because the method is done processing.
Any help would be appreciated, maybe I'm going about this the wrong way?
Can't use array lists or anything like that.
Here is my code.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class A2Q2
{
public static void main (String [] args)
{
processWords();
}
public static void processWords()
{
MyReader reader = new MyReader("A2Q2.txt");
String[] words = new String[174];
words[0] = reader.nextWord();
System.out.println(words[0]);
}
}
class MyReader
{
static String name;
static BufferedReader fileIn;
static String inputLine;
static int tokensLength = 0;
static String[] tokens;
static int counter = 0;
// constructor.
public MyReader(String name)
{
this.name = name;
}
public static String[] readFile()
{
String[] tokenz = new String[174];
int tokensLength = 0;
try
{
fileIn = new BufferedReader (new FileReader(name));
inputLine = fileIn.readLine();
while(inputLine !=null)
{
tokens = inputLine.split("\\s+");
for (int i = 0 ; i < tokens.length; i++)
{
int j = i + tokensLength;
tokenz[j] = tokens[i];
}
tokensLength = tokensLength + tokens.length;
inputLine = fileIn.readLine();
}
fileIn.close();
}
catch (IOException ioe)
{
System.out.println(ioe.getMessage());
ioe.printStackTrace();
}
//FULL ARRAY OF STRINGS IN TOKENZ
return tokenz;
}
public static String nextWord()
{
String[] tokenzz = readFile();
//????
return tokenzz[0];
}
}
Here's a conceptual model for you.
Keep track of your MyReader's state to know which value to return next.
the following example uses tokenIndex to decide where to read at next.
class MyReader
{
String[] tokens;
int tokenIndex = 0;
public String nextWord()
{
if(tokens == null || tokens.length <= tokenIndex)
{
// feel free to replace this line with whatever logic you want to
// use to fill in a new line.
tokens = readNextLine();
tokenIndex = 0;
}
String retVal = tokens[tokenIndex];
tokenIndex++;
return retval;
}
}
Mind you, this isn't a complete solution(it doesn't check for the end of file for instance), only a demonstration of the concept. You might have to elaborate a bit.
Use a loop and process each element in the array, printing them one at a time?