I want to split file as Header with detail in a list based on sequence.
want to split the text file using Header and detail I tried something like this but doesn't help.
I wanted to call previous iteration of iterator but I couldn't...
File :
H>>>>>>
L>>>>>>>
L>>>>>>>
L>>>>>>>
H>>>>>>>
L>>>>>>>
L>>>>>>>
H>>>>>>>
L>>>>>>> ...
I wanted :
List 1 with H , L , L ,L
List 2 with H , L , L
List 3 with H , L
Code Tried :
List<String> poString = new ArrayList<String>();
if(poString !=null && poString.size() > 0)
{
ListIterator<String> iter = poString.listIterator();
while(iter.hasNext())
{
String tempHead = iter.next();
List<String> detailLst = new ArrayList<String>();
if(tempHead.startsWith("H"))
{
while(iter.hasNext())
{
String detailt = iter.next();
if(!detailt.startsWith("H"))
detailLst.add(detailt);
else
{
iter.previousIndex();
}
}
}
}
Try this (untested):
BufferedReader br = new BufferedReader(new FileReader("file.txt"));
try {
List<StringBuilder> myList = new List<StringBuilder>();
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
if (line[0] == 'H')
{
myList.add(sb);
sb = new StringBuilder();
}
sb.append(line[0]);
line = br.readLine();
}
} finally {
br.close();
}
as far as I understood, eventually how many H..lines in your file, how many List<String> would you want to have.
If you don't know the exact number, (in your example, it is 3) then you have a List of List (List<List<String>>).
//read the file, omitted
List<List<String>> myList = new ArrayList<<List<String>>();
List<String> lines = null;
boolean createList = false;
while (line != null) {
if (line.startsWith("H")){
myList.add(lines);
lines = new ArrayList<String>();
}
//if the 1st line of your file not starting with 'H', NPE, you have to handle it
lines.add(line);
line=readnextlineSomeHow(); //read next line
}
the above codes may not work out of box, but it gives you the idea.
Try this, I've tried a little on my own and it works
BufferedReader br = new BufferedReader(new FileReader("file.txt"));
ArrayList<ArrayList<String>> result = new ArrayList<> ();
int numlines =0;
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
if (line.startsWith("H"))
{
result.add(new ArrayList<String>());
result.get(numlines).add("H");
line = br.readLine();
while(line != null && !line.startsWith("H")){
if(line.startsWith("L")) result.get(numlines).add("L");
line = br.readLine();
}
++numlines;
}
else line = br.readLine();
}
} finally {
br.close();
}
You can use this..
public static void main(String a[]) throws Exception
{
ArrayList<String> headers=new ArrayList();
ArrayList<String> lines=new ArrayList();
HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
File f= new File("inputfile.txt");
Scanner scanner = new Scanner(f);
try {
while (scanner.hasNextLine()){
String ss=scanner.nextLine();
String key= String.valueOf(ss.charAt(0));
if ( map.containsKey(key))
{
ArrayList<String> temp=(ArrayList) map.get(key);
temp.add(ss);
map.put(key, temp);
}
else
{
ArrayList<String> temp= new ArrayList();
temp.add(ss);
map.put(key, temp);
}
}
}
catch(Exception e)
{
throw e;
}
}
Related
I need to parse a text file in the form:
Encanto, 6/101-105, 7/320-322
Flora, 1/2-5
Vista, 7/67-70
WORK ORDER
I know how to parse a .txt file that has lines in the form "name, number" into two separate ArrayLists using the following method:
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
String line;
while( (line = bufferedReader.readLine()) != null){
allNames.add(line.split(", ")[0]);
allNums.add(Integer.parseInt(line.split(",\\s+")[1]));
}
bufferedReader.close();
Now I must get the Lists to have these items:
ArrayList<String> names = {"Encanto", "Flora", "Vista", "WORK ORDER"};
ArrayList<String> lots = {"Bld.6 101", "Bld.6 102", "Bld.6 103", "Bld.6 104", "Bld.6 105", "Bld.7 320", "Bld.7 321", "Bld.7 322"};
ArrayList<String> lots1 = {"Bld.1 2", "Bld.1 3", "Bld.1 4", "Bld.1 5",};
ArrayList<String> lots2 = {"Bld.7 67", "Bld.7 68", "Bld.7 69", "Bld.7 70"};
Create this Parser class
class Parser {
String parseName(String line) {
String[] blocks = line.split(", ");
if (blocks.length > 0) {
return blocks[0];
}
return null;
}
List<String> getLots(String line) {
List<String> lotList = new ArrayList<>();
String[] blocks = line.split(", ");
for (String block : blocks) {
// I suppose that lot line will always have "/" and "-"
if (block.contains("/") && block.contains("-")) {
lotList.addAll(generateLots(block));
}
}
return lotList;
}
private List<String> generateLots(String block) {
List<String> lots = new ArrayList<>();
String prefix = "Bld.";
String bldNumber = block.substring(0, block.indexOf("/"));
int lowest = Integer.parseInt(block.substring(block.indexOf("/") + 1, block.indexOf("-")));
int highest = Integer.parseInt(block.substring(block.indexOf("-") + 1, block.length()));
for (int i = lowest; i <= highest; i++) {
lots.add(prefix + bldNumber + " " + i);
}
return lots;
}
}
Then use it in your code
// create a new Parser object
Parser parser = new Parser();
// get name
System.out.println(parser.parseName(line));
// get lots
List<String> lotList = parser.getLots(line);
for (String lot : lotList) {
System.out.println(lot);
}
=========================================================
Edit:
To answer your comment, you can create lot lists on the fly. If I refer to your question, it will be like this
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
String line;
Parser parser = new Parser();
List<String> names = new ArrayList<>();
List<List<String>> lotsList = new ArrayList<>();
while ((line = bufferedReader.readLine()) != null) {
names.add(parser.parseName(line));
lotsList.add(parser.getLots(line));
}
bufferedReader.close();
I want to fill an array with names. The array should be filled depending on what gender the character is.
public void fillNameArray() throws IOException {
Character character = new Character(); //Declare and initialise character object
if(character.getGender() == "F"){
List<String> lines = new ArrayList<String>();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("femaleNames.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
} finally {
reader.close();
}
String[] array = (String[]) lines.toArray();
}
else{
List<String> lines = new ArrayList<String>();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("maleNames.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
} finally {
reader.close();
}
String[] array = (String[]) lines.toArray();
}
}
The problem is in the following line:
String[] array = (String[]) lines.toArray();
Write instead:
String[] array = lines.toArray(new String[lines.size()]);
See post as example.
Please can you also move the read code on a own method? So less code duplication.
public List<String> readNames(String file) {
List<String> lines = new ArrayList<String>();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
String line = null;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
} finally {
reader.close();
}
return lines;
}
I'm really stucked on this one. I'm wondering if it's possible to exclude all the elements from arraylist on reading a file? Thank you in advance!
I have elements on my arraylist(excludelist) like this:
test1
test2
test3
And I have csv data on my file(readtest) like this:
test1,off
test2,on
test3,off
test4,on
so what i'm expecting is to exclude all the data from arraylist in while loop then will be output like this :
test4,on
This is my code:
String exclude = "C:\\pathtomyexcludefile\\exclude.txt";
String read = "C:\\pathtomytextfile\\test.txt";
File readtest = new File(read);
File excludetest = new File(exclude);
ArrayList<String> excludelist = new ArrayList();
excludelist.addAll(getFile(excludetest));
try{
String line;
LineIterator it = FileUtils.lineIterator(readtest,"UTF-8");
while(it.hasNext()){
line = it.nextLine();
//determine here
}
catch(Exception e){
e.printStackTrace();
}
public static ArrayList<String> getFile(File file) {
ArrayList<String> data = new ArrayList();
String line;
try{
LineIterator it = FileUtils.lineIterator(file,"UTF-8");
while(it.hasNext()){
line = it.nextLine();
data.add(line);
}
it.close();
}
catch(Exception e){
e.printStackTrace();
}
return data;
}
There might be more efficient ways to do this, but you can inspect each line you're reading using String.startsWith against each element in the excludeList. If the line does not start with a to-be-excluded word, add it to the approvedLines list.
String exclude = "C:\\pathtomyexcludefile\\exclude.txt";
String read = "C:\\pathtomytextfile\\test.txt";
File readtest = new File(read);
File excludetest = new File(exclude);
List<String> excludelist = new ArrayList<>();
excludelist.addAll(getFile(excludetest));
List<String> approvedLines = new ArrayList<>();
LineIterator it = FileUtils.lineIterator(readtest, "UTF-8");
while (it.hasNext()) {
String line = it.nextLine();
boolean lineIsValid = true;
for (String excludedWord : excludelist) {
if (line.startsWith(excludedWord)) {
lineIsValid = false;
break;
}
}
if (lineIsValid) {
approvedLines.add(line);
}
}
// check that we got it right
for (String line : approvedLines) {
System.out.println(line);
}
If your excluded elements are a a String objects, you can try something like this:
while(it.hasNext()){
line = it.nextLine();
for(String excluded : excludelist){
if(line.startsWith(excluded)){
continue;
}
}
}
This is data.csv file, now I want rows having classtype x (any number) and store those extarcted rows into new array, so if i have n classtype then i will have n new arrays.
age sex zipcode classtype
21 m 23423 1
12 f 23133 2
23 m 32323 2
23 f 23211 1
Example: If I want to retrieve rows which have classtype 1 and store this values in a new 2d array. Then output should come like this:
array1={{21,m,23423,1},{23,f,23211,1}}
I have written the below code which gives me arrayList as output.
public class CsvParser {
public static void main(String[] args) {
try {
FileReader fr = new FileReader((args.length > 0) ? args[0] : "data.csv");
Map<String, List<String>> values = parseCsv(fr, "\\s,", true);
System.out.println(values);
} catch (IOException e) {
e.printStackTrace();
}
}
public static Map<String, List<String>> parseCsv(Reader reader, String separator, boolean hasHeader) throws IOException {
Map<String, List<String>> values = new LinkedHashMap<String, List<String>>();
List<String> columnNames = new LinkedList<String>();
BufferedReader br = null;
br = new BufferedReader(reader);
String line;
int numLines = 0;
while ((line = br.readLine()) != null) {
if (StringUtils.isNotBlank(line)) {
if (!line.startsWith("#")) {
String[] tokens = line.split(separator);
if (tokens != null) {
for (int i = 0; i < tokens.length; ++i) {
if (numLines == 0) {
columnNames.add(hasHeader ? tokens[i] : ("row_"+i));
} else {
List<String> column = values.get(columnNames.get(i));
if (column == null) {
column = new LinkedList<String>();
}
column.add(tokens[i]);
values.put(columnNames.get(i), column);
}
}
}
++numLines;
}
}
}
return values;
}
The ouput of this code is:
{age=[21,12,23,23],sex=[m,f,m,f],zipcode=[23423,23133,32323,23211],classtype=[1,2,2,1]}
I got few links, which says about grouping elements in "java collectors class", But dont whether that is useful.
http://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#groupingBy-java.util.function.Function-
Your help will be very useful.
You can try something like
String[][] allArrays = new String[50][]; //Set it to however many you need
String classType = "1";
int counter = 0;
Scanner s = new Scanner(new File(fileName));
while(s.hasNextLine()) {
String row = s.nextLine();
if (row.endsWith(classType) {
allArrays[counter++] = row.split(","); //Adds the row, with each element being split by the comma
}
}
Do not reinvent the wheel, you can use an existing library to dump the content of CSV file to a Java Collection. I usually use OpenCSV to dump the contents of CSV file to List<String[]>. It has a one liner code to read all.
CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));
List<String[]> lines= reader.readAll();
Then iterate the list like this to do the grouping.
Map<String, List<String[]>> values = new LinkedHashMap<String, List<String[]>>();
for(String[] line : lines){
String key = line[4];
if(values.get(key) == null){
values.put(key, new ArrayList<String[]>());
}
values.get(key).add(line);
}
System.out.println(values);
i am working on netbeans...i need to read a file and tokenize then and store it in an array for my future operations....i have attached the code where the line5 contains the tokens...while converting into array iam getting error as
Exception :
" Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1000
at preprocess.mainpage.jButton2ActionPerformed(mainpage.java:224)
at preprocess.mainpage.access$100(mainpage.java:18)
at preprocess.mainpage$2.actionPerformed(mainpage.java:62)"
Code:
int counter=-1;
int n=0;
String[] arr = new String[1000];
try
{
BufferedReader b = new BufferedReader(new FileReader("C:/Users/sky/Documents/NetBeansProjects/Preprocess/src/preprocess/cdr1.txt"));
String line;
while ((line = b.readLine()) != null)
{
counter+=1;
StringTokenizer st2 = new StringTokenizer(line, " ");
String line5 = (String) st2.nextElement();
arr[n] = line5;
n++;
}
}
catch (Exception e)
{
}
ArrayIndexOutOfBoundsException because may be your array size is less. So better use ArrayList like following:
int counter=-1;
int n=0;
//String[] arr = new String[1000];
List<String> list = new ArrayList<String>(); // Create ArrayList
try{
BufferedReader b = new BufferedReader(new FileReader("C:/Users/sky/Documents/NetBeansProjects/Preprocess/src/preprocess/cdr1.txt"));
String line;
while ((line = b.readLine()) != null) {
counter+=1;
StringTokenizer st2 = new StringTokenizer(line, " ");
String line5 = (String) st2.nextElement();
//arr[n] = line5;
//n++;
list.add(line5); // Add you string into list
}
String[] aa = list.toArray(new String[0]); // convert list into String of array if you need it
}
catch (Exception e){
}