Correcting and Condensing Java Program - java

I think I've almost figured out my java program. It is designed to read a text file and find the largest integer by using 10 different threads. I'm getting this error though:
Error:(1, 8) java: class Worker is public, should be declared in a file named Worker.java
I feel my code may be more complex than it needs to be so I'm trying to figure out how to shrink it down in size while also fixing the error above. Any assistance in this matter would be greatly appreciated and please let me know if I can clarify anything. Also, does the "worker" class have to be a seperate file? I added it to the same file but getting the error above.
import java.io.BufferedReader;
import java.io.FileReader;
public class datafile {
public static void main(String[] args) {
int[] array = new int[100000];
int count;
int index = 0;
String datafile = "dataset529.txt"; //string which contains datafile
String line; //current line of text file
try (BufferedReader br = new BufferedReader(new FileReader(datafile))) { //reads in the datafile
while ((line = br.readLine()) != null) { //reads through each line
array[index++] = Integer.parseInt(line); //pulls out the number of each line and puts it in numbers[]
}
}
Thread[] threads = new Thread[10];
worker[] workers = new worker[10];
int range = array.length / 10;
for (count = 0; count < 10; count++) {
int startAt = count * range;
int endAt = startAt + range;
workers[count] = new worker(startAt, endAt, array);
}
for (count = 0; count < 10; count++) {
threads[count] = new Thread(workers[count]);
threads[count].start();
}
boolean isProcessing = false;
do {
isProcessing = false;
for (Thread t : threads) {
if (t.isAlive()) {
isProcessing = true;
break;
}
}
} while (isProcessing);
for (worker worker : workers) {
System.out.println("Max = " + worker.getMax());
}
}
}
public class worker implements Runnable {
private int startAt;
private int endAt;
private int randomNumbers[];
int max = Integer.MIN_VALUE;
public worker(int startAt, int endAt, int[] randomNumbers) {
this.startAt = startAt;
this.endAt = endAt;
this.randomNumbers = randomNumbers;
}
#Override
public void run() {
for (int index = startAt; index < endAt; index++) {
if (randomNumbers != null && randomNumbers[index] > max)
max = randomNumbers[index];
}
}
public int getMax() {
return max;
}
}

I've written a few comments but I'm going to gather them all in an answer so anyone in future can see the aggregate info:
At the end of your source for the readtextfile class (which should be ReadTextile per java naming conventions) you have too many closing braces,
} while (isProcessing);
for (Worker worker : workers) {
System.out.println("Max = " + worker.getMax());
}
}
}
}
}
The above should end on the first brace that hits the leftmost column. This is a good rule of thumb when making any Java class, if you have more than one far-left brace or your last brace isn't far-left you've probably made a mistake somewhere and should go through checking your braces.
As for your file issues You should have all your classes named following Java conventions and each class should be stored in a file called ClassName.java (case sensitive). EG:
public class ReadTextFileshould be stored in ReadTextFile.java
You can also have Worker be an inner class. To do this you could pretty much just copy the source code into the ReadTextFile class (make sure it's outside of the main method). See this tutorial on inner classes for a quick overview.
As for the rest of your question Code Review SE is the proper place to ask that, and the smart folks over there probably will provide better answers than I could. However I'd also suggest using 10 threads is probably not the most efficient way in to find the largest int in a text file (both in development and execution times).

Related

System.out.println doesn't show text in console (IntelliJ)

I am writing a program which part is presented below:
public class Portal {
private String name;
private int[] positions; // positions of "ship"
private static int moves = 0; // moves made by player to sink a ship
public static int shot; // the value of position given by player
private int hits = 0; // number of hits
private int maxSize = 4; // max size of ship (the size will be randomized)
int first; // position of 1st ship block
int size; // real size of ship (randomized in setPortal method)
public void checkIfHit(){
for (int i : positions){
if (i == shot){
System.out.println("Hit confirmed");
hits++;
} else if (hits == positions.length){
System.out.println("Sunk");
} else {
System.out.println("Missed it");
}
}
moves++;
}
public void setPortal(){
size = 1 + (int)Math.random()*maxSize;
for (int i = 0; i < size - 1; i++){
if (i == 0){
positions[i]= 1 + (int)Math.random()*positions.length;
first = positions[i];
System.out.println(positions[i]);
continue;
}
positions[i]= first + 1;
System.out.println(positions[i]);
}
}
}
public class Main{
public static void main(String[] args){
// write your code here
Portal p1 = new Portal();
p1.setPortal();
}
}
code is split in two Java .class files.
The problem I'm dealing with is that using p1.setPortal(); doesn't show up text in IntelliJ console. The program works though and returns 0.
I don't have such problem in another program when I've put System.out.println in method other than main (also in separate class file).
What may be the cause of such issue?
It should properly throw an exception, because you forgot to initialize the integer array.
Have a look at this thread: Do we need to initialize an array in Java?
The Java's default value is null for an integer array. So your for wont even loop trough. The only thing that wonders me is why there is no exception..

Java - I need to print this string of characters to a string I can use out of loop

I have been buried in this assignment for 2 days chasing down rabbit holes for possible solutions. I am beginner Java, so I am sure this shouldn't be as difficult as I am making it.
I trying to program the infamous Java Bean Machine... My professor want the Class Path to return a String Variable that only holds "R" "L" . to represent the path of the dropped ball.
Each ball should have its own Path... I can get the path... but I can not get the path to print in a string outside of the for/if statement.
Here are his instructions... in case you can see if I am interpreting this incorrectly.
Please help!! Thank you in advance for sifting through this....
my code so far ******** i have updated the code to reflect the suggestions.. Thank you... ***************** New problem is it repeats the series of letters in a line... I only need a string of 6 char ....(LRLLRL)
public class Path {
StringBuilder myPath;
public Path() {
myPath = new StringBuilder();
}
void moveRight() {
myPath.append("R");
}
void moveLeft() {
myPath.append("L");
}
public void fallLevels(int levels) {
levels = 6;
for (int i = 0; i < (levels); i++) {
if (Math.random() < 0.5) {
this.moveRight();
} else {
this.moveLeft();
}
}
}
public String getPath() {
System.out.print(myPath.toString());
return myPath.toString();
}
}
}
******Thank you all.. this class now returns the correct string for one ball...***************
here is my code so far for multiple balls... I can get a long continuous string of 6 character sequences... I need each sequence to be a searchable string...I am not sure if I need to alter the Path class or if its something in the simulateGame() method. I think I can take it after this hump... Thank you again....
public class BeanMachine {
int numberOfLevels;
int[] ballsInBins;
Path thePath = new Path();
public BeanMachine(int numberOfLevels) {
this.numberOfLevels = 6;
ballsInBins = new int[this.numberOfLevels + 1];
// this.numberOfLevels +
}
public void simulateGame(int number) {
//looping through each ball
for (int i = 0; i < numberOfLevels -1; i++) {
thePath.fallLevels(0);
}
thePath.getPath().toString();
}
*** this isn't the entire code for this class... I have to get this method correct to continue....
Problem with your code:
if (Math.random() < 0.5) {
**loop = this.myPath = "R";**
} else {
**loop = this.myPath ="L";**
}
Change this to:
if (Math.random() < 0.5) {
**loop = this.myPath + "R";**
} else {
**loop = this.myPath + "L";**
}
Just added ** to highlight where there is wrong in your code

Having trouble using locks correctly

I thought I had a fairly decent understanding of locks and basic multi-threading concepts, but I'm royally messing something up here.
All the program is supposed to do is receive a filename for a text file and the number of threads you want to use from the user, and then count the number of "http" links in that file before returning that number to the user.
For the life of me, however, I can't get my threads to count properly. I've tried making the "count" variable an atomic integer and using the "incrementAndGet()" function, I've tried placing locks in the code where I thought they should be, and I've tried specifying the necessary functions are synchronized, all to no avail.
I've been doing the reading that I can on locks, concurrency, and whatnot, but I'm apparently doing something very wrong. Could someone explain to me where/why I need to be placing locks in my code (or how to properly use atomic integers, if that would be more effective)?
I originally had a lock for when the "count" variable was used (outside of any loops so it actually did something), but I'm receiving all kinds of numbers when I run the program.
My code looks like this:
import java.io.*;
import java.util.*;
import java.util.concurrent.locks.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Count
{
static String fname;
static int count = 0;
public static void main(String[] arg)
{
Scanner in = new Scanner(System.in);
int numthreads;
if( arg.length > 0 )
{
fname = arg[0];
numthreads = Integer.parseInt(arg[1]);
}
else
{
System.out.println("File?");
fname = in.nextLine();
System.out.println("Num threads?");
numthreads = in.nextInt();
}
RandomAccessFile raf;
try
{
raf = new RandomAccessFile(fname,"r");
Thread[] T = new Thread[numthreads];
for(int i=0;i<numthreads;++i)
{
T[i] = new Thread(new Task(i,numthreads,raf));
T[i].start();
}
for(Thread t : T)
{
try
{
t.join();
}
catch (InterruptedException e)
{
System.out.println("Thread join failed!");
e.printStackTrace();
System.exit(0);
}
}
System.out.println("The total is: "+count);
}
catch(IOException e)
{
System.out.println("Could not read file");
}
}
}
class Task implements Runnable
{
int myid;
int totaltasks;
RandomAccessFile raf;
ReentrantLock L = new ReentrantLock();
public Task(int myid, int totaltasks, RandomAccessFile raf)
{
this.myid=myid;
this.totaltasks=totaltasks;
this.raf = raf;
}
#Override
public void run()
{
try
{
long filesize = raf.length(); //length of the entire file
long sz = filesize / totaltasks; //length of entire file divided by number of threads gives thread size
long start = myid*sz; // thread's number * size of thread. How we find start of thread in the file
raf.seek(start);
if(start != 0 )
{
raf.readLine();
}
while(raf.getFilePointer() < (start+sz))
{
String s = raf.readLine();
Scanner sc = new Scanner(s);
while(sc.hasNext())
{
String w = sc.next();
if( w.startsWith("http://"))
{
Count.count++;
}
}
}
}
catch(IOException e)
{
System.out.println("IO error!");
}
}
}
If there's bigger issues at work here than me needing to use locks in the proper places, please let me know and I'll at least have something to work with, but as far as I'm aware it should just be a matter of performing locks properly and I'm either not understanding how they work correctly or just putting them in all the wrong places.

Multi thread array sort Java

So hello!
I'm trying to sort int array with several threads. Now I've got something like this:
import java.util.Arrays;
public class MultiTread extends Thread{
int sizeOfArray;
public static int treadsN = 4;
public static int sortFrom;
public static int sortTo;
public MultiTread(int sizeOfArray, int treadsN) {
this.sizeOfArray = sizeOfArray;
this.treadsN = treadsN;
}
public MultiTread(int[] arrayToSort, int sizeOfArray) {
this.sizeOfArray = sizeOfArray;
}
public static int [] creatingArray(int sizeOfArray) {
int [] arrayToSort = new int[sizeOfArray];
int arrayLength = arrayToSort.length;
for (int counter = 0; counter<arrayLength; counter++){
arrayToSort[counter] = (int)(8000000*Math.random());
}
return arrayToSort;
}
public static int [] sortInSeveralTreads(final int [] arrayToSort){
int [] newArr = new int[arrayToSort.length];
int numberOfThreads = treadsN;
if (numberOfThreads == 0){
System.out.println("Incorrect value");
return arrayToSort;
}
if (numberOfThreads == 1){
Arrays.sort(arrayToSort);
System.out.println("Array sorted in 1 thread");
} else {
final int lengthOfSmallArray = arrayToSort.length/numberOfThreads;
sortFrom = 0;
sortTo = lengthOfSmallArray;
for (int progress = 0; progress < numberOfThreads; progress++){
final int [] tempArr = Arrays.copyOfRange(arrayToSort,sortFrom,sortTo);
new Thread(){public void run() {
Arrays.sort(tempArr);
}}.start();
sortFrom = sortTo;
sortTo += lengthOfSmallArray;
newArr = mergeSort(newArr, tempArr);
}
new Thread(){public void run() {
Arrays.sort(Arrays.copyOfRange(arrayToSort, arrayToSort.length-lengthOfSmallArray, arrayToSort.length));
}}.start();
newArr = mergeSort(newArr, arrayToSort);
}
return newArr;
}
public static int [] mergeSort(int [] arrayFirst, int [] arraySecond){
int [] outputArray = new int[arrayFirst.length+arraySecond.length];
while (arrayFirst.length != 0 && arraySecond.length != 0){
int counter = 0;
if (arrayFirst[0] < arraySecond[0]){
outputArray[counter] = arrayFirst[0];
counter++;
arrayFirst = Arrays.copyOfRange(arrayFirst, 1, arrayFirst.length);
}else {
outputArray[counter] = arraySecond[0];
counter++;
arraySecond = Arrays.copyOfRange(arraySecond, 1, arraySecond.length);
}
}
return outputArray;
}
public static void main(String[] args){
long startTime;
long endTime;
int [] a = creatingArray(8000000);
startTime = System.currentTimeMillis();
a = sortInSeveralTreads(a);
endTime = System.currentTimeMillis();
System.out.println(Thread.activeCount());
System.out.printf("Sorted by: %d treads in %.7f seconds %n", treadsN, (float)(endTime-startTime)*1e-6);
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.activeCount());
}
}
I know that it's not very good realization. All works fine but merge sort works too bad - it crashes... Error should be in that lines:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:3137)
at MultiTread.mergeSort(MultiTread.java:78)
at MultiTread.sortInSeveralTreads(MultiTread.java:61)
at MultiTread.main(MultiTread.java:94)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
What i'm doing wrong?
Well, you're running out of the memory allowed by use by the J.V.M..
I've not checked to see that your algorithm is correct, but you should try the code with a much smaller array to see if it works alright, say, 1000.
You make several copies of the array (or at least partial copies) throughout your program, in threads. Each thread then is allocating a large amount of data. For this reason, you may wish to reconsider your design, or you will continue to run into this problem. If you find no way to reduce this allocation and my next paragraph does not help you, then you may need to resort to the use of files to sort these large arrays, instead of attempting to hold everything in memory at once.
You can increase the heap size by following instructions on this page (first link I found, but it has the right information):
http://viralpatel.net/blogs/2009/01/jvm-java-increase-heap-size-setting-heap-size-jvm-heap.html
This will allow you to hold allocate more memory from your Java program.
Okay there are several issues:
First your array size is way too large. Which is why you are running out of Memory (8000000) should be tried with a low number say 1000. Even with that your code will probably crash elsewhere as it stands.
Second your code makes very little sense as it stands you are mixing static and non static calls ... e.g. Thread.currentThread().sleep(1000) is bizarre, you are not in the current Thread.
The thread creation where you perform Array.sort.
I suggest that first you create a simple multi-threaded program before dealing with sorting job. Also recommend that you implement Runnable interface rather than extending the Thread class to create your worker class.
while (arrayFirst.length != 0 && arraySecond.length != 0){
here it goes in infinite loop once the conditions are satisfied and hence the memory heap is getting OutOfMemoryError
It is not at all terminated so You should include some code to terminate this loop.

Encoding codes in Java

Over the past couple of weeks I've read through the book Error Control Coding: Fundamentals and Applications in order to learn about BCH (Bose, Chaudhuri, Hocquenghem) Codes for an junior programming role at a telecoms company.
This book mostly covers the mathematics and theory behind the subject, but I'm struggling to implement some of the concepts; primarily getting the next n codewords.I have a GUI (implemented through NetBeans, so I won't post the code as the file is huge) that passes a code in order to get the next n numbers:
Generating these numbers is where I am having problems. If I could go through all of these within just the encoding method instead of looping through using the GUI my life would be ten times easier.
This has been driving me crazy for days now as it is easy enough to generate 0000000000 from the input, but I am lost as to where to go from there with my code. What do I then do to generate the next working number?
Any help with generating the above code would be appreciated.
(big edit...) Playing with the code a bit more this seems to work:
import java.util.ArrayList;
import java.util.List;
public class Main
{
public static void main(final String[] argv)
{
final int startValue;
final int iterations;
final List<String> list;
startValue = Integer.parseInt(argv[0]);
iterations = Integer.parseInt(argv[1]);
list = encodeAll(startValue, iterations);
System.out.println(list);
}
private static List<String> encodeAll(final int startValue, final int iterations)
{
final List<String> allEncodings;
allEncodings = new ArrayList<String>();
for(int i = 0; i < iterations; i++)
{
try
{
final int value;
final String str;
final String encoding;
value = i + startValue;
str = String.format("%06d", value);
encoding = encoding(str);
allEncodings.add(encoding);
}
catch(final BadNumberException ex)
{
// do nothing
}
}
return allEncodings;
}
public static String encoding(String str)
throws BadNumberException
{
final int[] digit;
final StringBuilder s;
digit = new int[10];
for(int i = 0; i < 6; i++)
{
digit[i] = Integer.parseInt(String.valueOf(str.charAt(i)));
}
digit[6] = ((4*digit[0])+(10*digit[1])+(9*digit[2])+(2*digit[3])+(digit[4])+(7*digit[5])) % 11;
digit[7] = ((7*digit[0])+(8*digit[1])+(7*digit[2])+(digit[3])+(9*digit[4])+(6*digit[5])) % 11;
digit[8] = ((9*digit[0])+(digit[1])+(7*digit[2])+(8*digit[3])+(7*digit[4])+(7*digit[5])) % 11;
digit[9] = ((digit[0])+(2*digit[1])+(9*digit[2])+(10*digit[3])+(4*digit[4])+(digit[5])) % 11;
// Insert Parity Checking method (Vandermonde Matrix)
s = new StringBuilder();
for(int i = 0; i < 9; i++)
{
s.append(Integer.toString(digit[i]));
}
if(digit[6] == 10 || digit[7] == 10 || digit[8] == 10 || digit[9] == 10)
{
throw new BadNumberException(str);
}
return (s.toString());
}
}
class BadNumberException
extends Exception
{
public BadNumberException(final String str)
{
super(str + " cannot be encoded");
}
}
I prefer throwing the exception rather than returning a special string. In this case I ignore the exception which normally I would say is bad practice, but for this case I think it is what you want.
Hard to tell, if I got your problem, but after reading your question several times, maybe that's what you're looking for:
public List<String> encodeAll() {
List<String> allEncodings = new ArrayList<String>();
for (int i = 0; i < 1000000 ; i++) {
String encoding = encoding(Integer.toString(i));
allEncodings.add(encoding);
}
return allEncodings;
}
There's one flaw in the solution, the toOctalString results are not 0-padded. If that's what you want, I suggest using String.format("<something>", i) in the encoding call.
Update
To use it in your current call, replace a call to encoding(String str) with call to this method. You'll receive an ordered List with all encodings.
I aasumed, you were only interested in octal values - my mistake, now I think you just forgot the encoding for value 000009 in you example and thus removed the irretating octal stuff.

Categories

Resources