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);
}
Related
when there is a reading of lines and work with them continues line by line
I need to accept multi-line input first and only then to work the code
public class OrderRestaurant {
public static void main(String[] args) throws IOException {
InputStreamReader reader = new InputStreamReader(System.in, StandardCharsets.UTF_8);
BufferedReader in = new BufferedReader(reader);
String line = null;
TreeMap<String, LinkedList<Integer>> orderMap = new TreeMap<String, LinkedList<Integer>>();
Set<Integer> tableSet = new TreeSet<Integer>();
while ((line = in.readLine()) != null) {
String[] orders = line.split(",");
for (int i = 0; i < orders.length; i++) {
tableSet.add(Integer.parseInt(orders[1]));
}
if (!(orderMap.containsKey(orders[2]))) {
LinkedList<Integer> numbersTables = new LinkedList<>();
numbersTables.add(Integer.parseInt(orders[1]));
orderMap.put(orders[2], numbersTables);
} else {
orderMap.get(orders[2]).addLast(Integer.parseInt(orders[1]));
}
StringBuilder sBuilder = new StringBuilder("Table");
Set<String>keysOrderMapSet=orderMap.keySet();
for (String keyString : keysOrderMapSet) {
sBuilder.append(',').append(keyString);
}
for(Integer key : tableSet){
sBuilder.append("\n").append(key);
for(Map.Entry<String, LinkedList<Integer>> entry : orderMap.entrySet())
{
LinkedList<Integer> numbersOrder = entry.getValue();
int counterOrder = 0;
for (int i = 0; i < numbersOrder.size(); i++) {
if(numbersOrder.get(i)==key) {
counterOrder++;
}
}
sBuilder.append(',').append(counterOrder);
}
}
System.out.println(sBuilder.toString());
}
}
}
all input is green, further you can see that the output after the program runs is formed in parts and only at the end is displayed in its entirety.
What I understand from the question is that you want to read all lines from the console first then need to do any operation or work and after that, you want to print the result for each line on the console. If that is the case then you need to create an intermediate array or list to hold the data of each line. Please refer below steps:
Create an empty list as readLineByLineString that holds your input line by line.
Read line from the console using Scanner or BufferedReader.
Add that line to the list by readLineByLineString.add(line);
Read all the lines and add to the list until all test cases satisfy or required conditions.
Now you have all your data line by line in an intermediate list i.e. readLineByLineString, just do the required operation.
Print your result after each operation.
End
You can read for example 1024 bytes at a time.
char[] myBuffer = new char[512];
int bytesRead = 0;
BufferedReader in = new BufferedReader(new FileReader(reader));
while ((bytesRead = in.read(myBuffer,0,1024)) != -1)
{ ... }
Please I will like to adjust this code that reads integers from a file.
I will like the code to detect the number (n) of the dataset instead of having to put in figures manually as done below (4000 )
double[] tall = new double[4000];
public class Extracto {
public static void main(String[] args) throws IOException {
File fil = new File("C:\\Users\\Desktop\\kaycee2.csv");
FileReader inputFil = new FileReader(fil);
BufferedReader in = new BufferedReader(inputFil);
double[] tall = new double[4000];
String s = in.readLine();
int i = 0;
while (s != null) {
// Skip empty lines.
s = s.trim();
if (s.length() == 0) {
continue;
}
tall[i] = Double.parseDouble(s); // This is line 19.
// System.out.println(tall[i]);
s = in.readLine();
i++;
}
I am expecting the adjusted code to obtain the data length without manually putting it in like in as shown in the code below for the 4000 length.
double[] tall = new double[4000];
As Thomas mentioned, use a list, instead of an array.
File fil = new File("C:\\Users\\Desktop\\kaycee2.csv");
FileReader inputFil = new FileReader(fil);
BufferedReader in = new BufferedReader(inputFil);
ArrayList<Double> tall = new ArrayList<>();
while(in.ready()){
String s = in.readLine().trim();
if(!s.isEmpty()){
tall.add(Double.parseDouble(s);
}
}
your codes can be further compacted if you use a list.
also do add a try-catch in the event when the String read is not a number.
For now in my program i am using hard-coded values, but i want it so that the user can use any text file and get the same result.
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.File;
public class a1_12177903
{
public static void main(String [] args) throws IOException
{
if (args[0] == null)
{
System.out.println("File not found");
}
else
{
File file = new File(args[0]);
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String line = "";
while (br.ready())
{
line += br.readLine();
}
String[] work = line.split(",");
double[] doubleArr = new double[work.length];
for (int i =0; i < doubleArr.length; i++)
{
doubleArr[i] = Double.parseDouble(work[i]);
}
double maxStartIndex=0;
double maxEndIndex=0;
double maxSum = 0;
double total = 0;
double maxStartIndexUntilNow = 0;
for (int currentIndex = 0; currentIndex < doubleArr.length; currentIndex++)
{
double eachArrayItem = doubleArr[currentIndex];
total += eachArrayItem;
if(total > maxSum)
{
maxSum = total;
maxStartIndex = maxStartIndexUntilNow;
maxEndIndex = currentIndex;
}
if (total < 0)
{
maxStartIndexUntilNow = currentIndex;
total = 0;
}
}
System.out.println("Max sum : "+ maxSum);
System.out.println("Max start index : "+ maxStartIndex);
System.out.println("Max end index : " +maxEndIndex);
}
}
}
I've fixed it so it takes in the name of the text file from the command line. if anyone has any ways to improve this, I'll happily accept any improvments.
You can do this with Java8 Streams, assuming each entry has it's own line
double[] doubleArr = Files.lines(pathToFile)
.mapToDouble(Double::valueOf)
.toArray();
If you were using this on production systems (rather than as an exercise) it would be worth while to create the Stream inside a Try with Resources block. This will make sure your input file is closed properly.
try(Stream<String> lines = Files.lines(path)){
doubleArr = stream.mapToDouble(Double::valueOf)
.toArray();
}
If you have a comma separated list, you will need to split them first and use a flatMap.
double[] doubleArr = Files.lines(pathToFile)
.flatMap(line->Stream.of(line.split(","))
.mapToDouble(Double::valueOf)
.toArray();
public static void main(String[] args) throws IOException {
String fileName = "";
File inputFile = new File(fileName);
BufferedReader br = new BufferedReader(new FileReader(inputFile));
// if input is in single line
StringTokenizer str = new StringTokenizer(br.readLine());
double[] intArr = new double[str.countTokens()];
for (int i = 0; i < str.countTokens(); i++) {
intArr[i] = Double.parseDouble(str.nextToken());
}
// if multiple lines in input file for a single case
String line = "";
ArrayList<Double> arryList = new ArrayList<>();
while ((line = br.readLine()) != null) {
// delimiter of your choice
for (String x : line.split(" ")) {
arryList.add(Double.parseDouble(x));
}
}
// convert arraylist to array or maybe process arrayList
}
This link may help: How to use BufferedReader. Then you will get a String containing the array.
Next you have several ways to analyze the string into an array.
Use JSONArray to parse it. For further information, search google for JSON.
Use the function split() to parse string to array. See below.
Code for way 2:
String line="10,20,50";//in fact you get this from file input.
String[] raw=line.split(",");
String[] arr=new String[raw.length];
for(int i=0;i<raw.length;++i)arr[i]=raw[i];
//now arr is what you want
Use streams if you are on JDK8. And please take care of design principles/patterns as well. It seems like a strategy/template design pattern can be applied here. I know, nobody here would ask you to focus on design guidelines.And also please take care of naming conventions. "File" as class name is not a good name.
The code reads from text file and goes true all 1000 words in txt. It then read each word calculate ist lenght and from that lenght gets random number (say lenght is 4 and random would be 2). It then replaces that random numbers character with "*". This would be later used as an sample into main program.
Problem is at the moment i am getting same as an result multiple times.
TXT:
http://textuploader.com/oyfi
public class random_2 {
public static void main(String[] args) {
int dolzina = 0;
Object s;
String outputFile = "random_2.txt";
ArrayList<String> list = new ArrayList();
try {
File file = new File("random1.txt");
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String vrstica;
while ((vrstica = bufferedReader.readLine()) != null) {
list.add(vrstica);
// dolzina=list.size();
// System.out.println(dolzina);
}
FileWriter fileWriter = new FileWriter(outputFile);
PrintWriter out = new PrintWriter(fileWriter);
for (int idx = 0; idx <= list.size(); ++idx) {
String test=list.get(idx);
dolzina=test.length();
Random randomGenerator = new Random();
for (int i = 0; i<= dolzina; ++i) {
int randomInt = randomGenerator.nextInt(dolzina);
StringBuilder beseda = new StringBuilder(test);
beseda.setCharAt(randomInt, '*');
System.out.println(beseda);
}
}
System.out.println("Done.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
You must use the constructor
Random(long seed)
A random generator can be view as an object that have a predefined list number, and returning at each call the next number into the list.
Using the Random(long seed) will give the first index to start with into the list.
Here into your code, you always start the random list at position 0.
Concretely, we use for the 'seed' parameter the actual time in millisecond. So each time you run your program, you will initalize the random generator with a different start index, and you will get a different result each run time.
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;
}