I have a scenario, in which every timeslot has a profit and muliple jobs to choose from. I need to select the jobs at each time slot such that overall maximum profit is obtained. I require the maximum profit obtained and the schedule.
The only thing I can think of is to try for every comibnation using bruteforce. How can I solve this problem effectively.Is there any way I can do it better by using specific algorithm or data structure?
In the below example , any of the jobs J1,J2,J4 can be selected for timeslot1. Similarly for other time slots any one or none of the jobs can be selected. Only one job can be selected for a particular timeslot. If a job is done in one time slot, it cannot be done again.
Eg. If j1 is done in TS1, it cannot be picked again in TS2
+----------+--------+----------------------+
| TimeSlot | Profit | Possible Job |
+----------+--------+----------------------+
| 1 | 50 | J1 or J2 or J4 |
| 2 | 100 | J1 |
| 3 | 20 | J2 |
| 4 | 60 | J5 or J4 |
| 5 | 15 | J1 or J2 or J3 or J6 |
+----------+--------+----------------------+
This can be solved optimally by weighted maximum matching in bipartite graph.
In here, your graph is G=(U,V,E), where:
U = {1, 2, ...., n} // time slots
V = {J1, J2, ..., J_m} // jobs
E = { (i,J) | if job J can be done in time i }
w(i,J) = profit(i)
A maxmum matching in the above graph is translated directly to an optimal solution, by performing task J in timeslot i iff the maximum matching matched node J with node i.
public class JobProfitMaximizer {
private int numberOfJobs;
private Job[] jobs;
private int maxProfit;
public class JobComparator implements Comparator<Job> {
#Override
public int compare(Job arg0, Job arg1) {
if (arg0.end <= arg1.end)
return -1;
else
return 1;
}
}
public JobProfitMaximizer() {
numberOfJobs = 0;
maxProfit = 0;
}
private void printJobProfiles() {
for (Job j : jobs) {
System.out.println(j.start + " " + j.end + " " + j.profit);
}
}
private void createJobProfiles() {
jobs = new Job[numberOfJobs];
File inputFile = new File("***Filepath***********");
Scanner sc = null;
int jobCounter = 0;
try {
sc = new Scanner(inputFile);
while (sc.hasNextLine()) {
String s = sc.nextLine();
String[] profileOfJob = s.split(" ");
int start = Integer.parseInt(profileOfJob[1]);
int end = Integer.parseInt(profileOfJob[2]);
int profit = Integer.parseInt(profileOfJob[3]);
jobs[jobCounter] = new Job(start, end, profit);
jobCounter = jobCounter + 1;
}
} catch (FileNotFoundException e) {
System.out.println("The file is not present");
} finally {
try {
if (sc != null)
sc.close();
} catch (Exception f) {
System.out.println(f.getMessage());
}
}
}
private void setNumberOfJobs() {
File inputFile = new File("***Filepath***********");
Scanner sc = null;
int countOfJobs = 0;
try {
sc = new Scanner(inputFile);
while (sc.hasNextLine()) {
countOfJobs = countOfJobs + 1;
sc.nextLine();
}
numberOfJobs = countOfJobs;
System.out.println(numberOfJobs);
} catch (FileNotFoundException e) {
System.out.println("The file is not present");
} finally {
try {
if (sc != null)
sc.close();
} catch (Exception f) {
System.out.println(f.getMessage());
}
}
}
private void sortJobsOnFinishTimes() {
JobComparator jc = new JobComparator();
Arrays.sort(jobs, jc);
}
private void calculateMaximumProfit() {
int[] T = new int[numberOfJobs];
T[0] = jobs[0].profit;
for (int i = 1; i < numberOfJobs; i++) {
T[i] = Math.max(T[i - 1], jobs[i].profit);
for (int j = i - 1; j >= 0; j--) {
if (jobs[j].end <= jobs[i].start) {
T[i] = Math.max(T[i], T[j] + jobs[i].profit);
break;
}
}
}
int currentMaxProfitValue = T[0];
for (int m : T) {
if (m > currentMaxProfitValue) {
currentMaxProfitValue = m;
}
}
maxProfit = currentMaxProfitValue;
}
public static void main(String args[]) {
JobProfitMaximizer j = new JobProfitMaximizer();
j.setNumberOfJobs();
j.createJobProfiles();
j.sortJobsOnFinishTimes();
j.calculateMaximumProfit();
System.out.println("The maximum profit is " + j.maxProfit);
}
}
Related
ListTopVisitedSites(sites, 5) is supposed to return the following output:
www.google.com | 4
www.aol.com | 3
www.microsoft.com | 3
www.amazon.com | 3
www.facebook.com | 3
I am trying to print the top 5 elements. If multiple elements have the same quantity, they should be ordered by recency - (recently added). Also, I need to print an empty array of type string for no value.
Which part am I missing, or have coded incorrectly? All the methods and their parameters should remain the same, as I am supposed to keep the time complexity as N2 and space complexity as 1.
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
class SiteStats {
private String url;
private int numVisits;
public SiteStats(String url, int numVisits) {
this.url = url;
this.numVisits = numVisits;
}
public int getNumVisits() {
return this.numVisits;
}
public String getUrl() {
return this.url;
}
public void setNumVisits(int updatedNumVisits) {
this.numVisits = updatedNumVisits;
}
public String toString() {
return this.url + " | " + this.numVisits;
}
}
public class PartBSolution {
private static Queue<SiteStats> sites = new LinkedList<SiteStats>();
public static void listTopVisitedSites(Queue<SiteStats> sites, int n) {
sortQueue(sites);
while(sites.isEmpty()== false)
{
System.out.println(sites.peek() + " ");
sites.poll();
}
}
public static void insertMaxToRear(Queue<SiteStats> sites,
int max_index)
{
SiteStats max_value = null;
int s = sites.size();
for (int i = 0; i < s; i++)
{
SiteStats current = sites.peek();
sites.poll();
if (i != max_index)
sites.add(current);
else
max_value = current;
}
sites.add(max_value);
}
public static void sortQueue(Queue<SiteStats> sites)
{
for(int i = 1; i <= sites.size(); i++)
{
int max_index = maxIndex(sites,sites.size() - i);
insertMaxToRear(sites, max_index);
}
}
public static int maxIndex(Queue<SiteStats> sites,
int sortIndex)
{
int max_index = -1;
int max_value = 0;
int s = sites.size();
for (int i = 0; i < s; i++)
{
SiteStats current = sites.peek();
sites.poll();
if (current.getNumVisits() >= max_value && i <= sortIndex)
{
max_index = i;
max_value = current.getNumVisits();
}
sites.add(current);
}
return max_index;
}
public static void updateCount(String url) {
boolean flag=false;
int size2=sites.size();
for(int i = 0; i < size2 ; i++)
{
SiteStats temp=sites.peek();
sites.poll();
if(temp.getUrl().equals(url))
{
temp.setNumVisits(temp.getNumVisits()+1);
flag=true;
sites.add(temp);
break;
}
sites.add(temp);
}
if(!flag)
sites.add(new SiteStats(url,1));
}
public static void main(String[] args) {
String[] visitedSites = { "www.google.com", "www.google.com", "www.facebook.com", "www.aol.com", "www.google.com", "www.youtube.com",
"www.facebook.com", "www.aol.com", "www.facebook.com", "www.google.com", "www.microsoft.com", "www.9gag.com", "www.netflix.com",
"www.netflix.com", "www.9gag.com", "www.microsoft.com", "www.amazon.com", "www.amazon.com", "www.uber.com", "www.amazon.com",
"www.microsoft.com", "www.aol.com" };
for (String url : visitedSites) {
updateCount(url);
}
listTopVisitedSites(sites, 5);
}
}
/**
www.google.com | 4
www.aol.com | 3
www.microsoft.com | 3
www.amazon.com | 3
www.facebook.com | 3
*/
The parameter n that you pass into listTopVisitedSites(sites, 5); is never used again, so you can not expect it to only list the 5
You did not write the logic for parameter n of listTopVisitedSites. Please find the updated one.
public static void listTopVisitedSites(Queue<SiteStats> sites, int n) {
sortQueue(sites);
int iterate = 1;
while (sites.isEmpty() == false && iterate <= n) {
System.out.println(sites.peek() + " ");
sites.poll();
iterate++;
}
}
I need to implement a "round-robin" scheduler with a job class that I cannot modify. Round-robin scheduler should process the job that has been waiting the longest first, then reset timer to zero. If two jobs have same wait time, lower id is processed first. The job class only gives three values (job id, remaining duration, and priority(which is not needed for this). each job has a start time, so only a couple of jobs may be available during first cycle, few more next cycle, etc. Since the "job array" I am calling is different every time I call it, I'm not sure how to store the wait times.
This is the job class:
public class Jobs{
private int[] stas = new int[0];
private int[] durs = new int[0];
private int[] lefs = new int[0];
private int[] pris = new int[0];
private int[] fins = new int[0];
private int clock;
public Jobs()
{
this("joblist.csv");
}
public Jobs(String filename)
{
BufferedReader fp = null;
String line = "";
String[] b = null;
int[] tmp;
try
{
fp = new BufferedReader(new FileReader(filename));
while((line = fp.readLine()) != null)
{
b = line.split(",");
if(b.length == 3)
{
try
{
int sta = Integer.parseInt(b[0]);
//System.out.println("sta: " + b[0]);
int dur = Integer.parseInt(b[1]);
//System.out.println("dur: " + b[1]);
int pri = Integer.parseInt(b[2]);
//System.out.println("pri: " + b[2]);
stas = app(stas, sta);
//System.out.println("stas: " + Arrays.toString(stas));
durs = app(durs, dur);
//System.out.println("durs: " + Arrays.toString(durs));
lefs = app(lefs, dur);
//System.out.println("lefs: " + Arrays.toString(lefs));
pris = app(pris, pri);
//System.out.println("pris: " + Arrays.toString(pris));
fins = app(fins, -1);
//System.out.println("fins: " + Arrays.toString(fins));
}
catch(NumberFormatException e) {}
}
}
fp.close();
}
catch(FileNotFoundException e) { e.printStackTrace(); }
catch(IOException e) { e.printStackTrace(); }
clock = 0;
}
public boolean done()
{
boolean done = true;
for(int i=0; done && i<lefs.length; i++)
if(lefs[i]>0) done=false;
return done;
}
public int getClock() { return clock; }
public int[][] getJobs()
{
int count = 0;
for(int i=0; i<stas.length; i++)
if(stas[i]<=clock && lefs[i]>0)
count++;
int[][] jobs = new int[count][3];
count = 0;
for(int i=0; i<stas.length; i++)
if(stas[i]<=clock && lefs[i]>0)
{
jobs[count] = new int[]{i, lefs[i], pris[i]};
count++;
}
return jobs;
}
public int cycle() { return cycle(-1); }
public int cycle(int j)
{
if(j>=0 && j<lefs.length && clock>=stas[j] && lefs[j]>0)
{
lefs[j]--;
if(lefs[j] == 0) fins[j] = clock+1;
}
clock++;
return clock;
}
private int[] app(int[] a, int b)
{
int[] tmp = new int[a.length+1];
for(int i=0; i<a.length; i++) tmp[i] = a[i];
tmp[a.length] = b;
return tmp;
}
public String report()
{
String r = "JOB,PRIORITY,START,DURATION,FINISH,DELAY,PRI*DELAY\n";
float dn=0;
float pdn=0;
for(int i=0; i<stas.length; i++)
{
if(fins[i]>=0)
{
int delay = ((fins[i]-stas[i])-durs[i]);
r+= ""+i+","+pris[i]+","+stas[i]+","+durs[i]+","+fins[i]+","+delay+","+(pris[i]*delay)+"\n";
dn+= delay;
pdn+= pris[i]*delay;
}
else
{
int delay = ((clock*10-stas[i])-durs[i]);
r+= ""+i+","+pris[i]+","+stas[i]+","+durs[i]+","+fins[i]+","+delay+","+(pris[i]*delay)+"\n";
dn+= delay;
pdn+= pris[i]*delay;
}
}
if(stas.length>0)
{
r+= "Avg,,,,,"+(dn/stas.length)+","+pdn/stas.length+"\n";
}
return r;
}
public String toString()
{
String r = "There are "+stas.length+" jobs:\n";
for(int i=0; i<stas.length; i++)
{
r+= " JOB "+i+": START="+stas[i]+" DURATION="+durs[i]+" DURATION_LEFT="+lefs[i]+" PRIORITY="+pris[i]+"\n";
}
return r;
}
I don't need full code, just an idea of how to store wait times and cycle the correct job.
While a array based solution 'may' work, I would advocate a more object oriented approach. Create 'Job' class with the desire attributes (id, start_time, wait etc). Using the csv file, create Job objects and hold them in a list. Write a comparator to sort this jobs-list (in this case based on job wait/age would be the factor).
The job executor then has to do the following:
while(jobs exist) {
iterate on the list {
if job is executable // start_time > current sys_time
consume cycles/job for executable jobs
mark completed jobs (optional)
}
remove the completed jobs
}
//\ This loop will add +1 to each job
for(int i = 0; i < jobs.length; i++)
{
waitTime[jobs[i][0]] += 1;
}
int longestWait = 0;//\ This holds value for greatest wait time
int nextJob = 0; //\ This holds value for index of job with greatest wait time
//\ this loop will check for the greatest wait time and and set variables accordingly
for(int i = 0; i < waitTime.length; i++)
{
if(waitTime[i] > longestWait)
{
longestWait = waitTime[i];
nextJob = i;
}
}
//\ this cycles the job with the highest wait time
jobsource.cycle(nextJob);
//\ this resets the wait time for processed job
waitTime[nextJob] = 0;
I have a problem dealing with thread communication in java. I am doing a project that will connect people to 3 different Elevators (depending on the floor they want to go) that have a capacity limit. The thing is I have three difficulties.
My code is Consumer-Producer problem based, and I don't know how to change it so the elevator doesn't wait for it to be full, but starts after time by itself.
Another one is that the program stops before completing the loops. (no idea why).
If i try to check if the elevator hasn't been chosen (by geting the capacity) and not display the info of it being back at floor 0, the program doesn't work.
My code: (Classes of elevator 2 and 3 and their buffers are identical)
public class Proba { //test class
public static void main(String[] args) {
Pojemnik c = new Pojemnik();
Pojemnik1 d = new Pojemnik1();
Pojemnik2 e = new Pojemnik2();
Winda p1 = new Winda(c, 1);
Winda1 p2 = new Winda1(d, 2);
Winda2 p3 = new Winda2(e, 3);
Osoba c1 = new Osoba(c, d, e, 1);
p1.start();
p2.start();
p3.start();
c1.start();
}
}
class Osoba extends Thread //person class
{
private Pojemnik pojemnik;
private Pojemnik1 pojemnik1;
private Pojemnik2 pojemnik2;
private int number;
public Osoba(Pojemnik c, Pojemnik1 d, Pojemnik2 e, int number) {
pojemnik = c;
pojemnik1 = d;
pojemnik2 = e;
this.number = number;
}
public void run() {
int value = 0;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++)
{
int k=0;
while (k==0){ //i dont; want floor 0
k = -2 + (int)(Math.random()*7);} //choosing floor
int h;
if(k>-3&&k<1){ //decision which elevator
value = pojemnik.get(); // getting possible capacity
if(value>0){
pojemnik.put(value-1);} //lowering capacity
h=5-value; // how many people are already in
System.out.println("Ktos wsiadl do windy #1"
//+ this.number
+ " jest w niej " + h + " osob i wybrano pietro nr " + k);
}
if(k>-1&&k<4){
value = pojemnik1.get();
if(value>0){
pojemnik1.put(value-1);}
h=5-value;
System.out.println("Ktos wsiadl do windy #2"
//+ this.number
+ " jest w niej " + h + " osob i wybrano pietro nr " + k);
}
if(k>3&&k<8){
value = pojemnik2.get();
if(value>0){
pojemnik1.put(value-1);}
h=5-value;
System.out.println("Ktos wsiadl do windy #3"
//+ this.number
+ " jest w niej " + h + " osob i wybrano pietro nr " + k);
}
}
}
}
}
//import java.util.*;
//import java.lang.*;
class Pojemnik //buffor class
{
private int contents;
private boolean available = false;
public synchronized int get() {
while (available == false) {
try {
wait();
}
catch (InterruptedException e) {
}
}
available = false;
notifyAll();
return contents;
}
public synchronized void put(int value) {
while (available == true) {
try {
wait();
}
catch (InterruptedException e) {
}
}
contents = value;
if(value>5){ //way to never get too high capacity
contents=5;
}
available = true;
notifyAll();
}
}
// import java.lang.*; // elevator class
class Winda extends Thread {
private Pojemnik pojemnik; //bufor
private int number;
public Winda(Pojemnik c, int number) {
pojemnik = c;
this.number = number;
}
public void run() {
for (int i = 0; i < 10; i++) {
//pojemnik.get();
pojemnik.put(5); // the elevator is empty 5 people can go in
System.out.println("Winda #" + this.number
+ " jest na poziomie 0 "); //info that elevator is on floor 0
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) { }
}
}
}
need some help with a maze solving program in java.
The program has to read a maze from a file, store it into an array, solve it, and display the solution in a drawing panel. I'm struggling storing it into an array, and I'm really unsure of how to move into solving it and displaying it. But if i could get some help on the array part to get into a groove, I'd really appreciate it.
Here is an example of an input file. I want it to work for any maze of this structure, (with +, -, S, E, and |). The first two numbers, (8, 10) represent the height and width, the # of rows and # of columns.
8 10
+-+-+-+-+-+-+-+-+-+
| |
+ +-+-+-+ +-+-+-+ +
| | | |
+ + +-+-+-+-+-+ + +
| | | | | |
+ + + +-+-+-+ + + +-+
| | | | | | | S|
+ + + + +-+ + + + +-+
| | | |E| | | |
+ + + +-+ +-+ + + +
| | | | | |
+ + +-+-+-+-+-+ + +
| | | |
+ +-+-+-+-+-+-+-+ +
| |
+-+-+-+-+-+-+-+-+-+
Here is my code so far:
import java.util.Arrays;
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
public class MazeSolver {
// The name of the file describing the maze
static String mazefile;
static int width;
static int height;
public static void main(String[] args) throws FileNotFoundException {
if (handleArguments(args)) {
readMazeFile(mazefile);
DrawMaze.draw();
if (solveMaze())
System.out.println("Solved!");
else
System.out.println("Maze has no solution.");
}
else {
System.out.println("The arguments are invalid.");
}
}
// Handle the input arguments
static boolean handleArguments(String[] args) {
if (args.length > 4 || args.length < 1) {
System.out.println("There are too many or too few command line arguments");
return false;
}
if (args.length == 1) {
String mazefile = args[0];
File file = new File(mazefile);
if (!file.canRead()) {
return false;
}
return true;
}
if (args.length == 2) {
String mazefile = args[0];
File file = new File(mazefile);
if (!file.canRead()) {
return false;
}
int cellsize = Integer.parseInt(args[1]);
if (cellsize < 10) {
return false;
}
return true;
}
if (args.length == 3) {
String mazefile = args[0];
File file = new File(mazefile);
if (!file.canRead()) {
return false;
}
int cellsize = Integer.parseInt(args[1]);
int borderwidth = Integer.parseInt(args[2]);
if (borderwidth < 5) {
return false;
}
return true;
}
if (args.length == 4) {
String mazefile = args[0];
File file = new File(mazefile);
if (!file.canRead()) {
return false;
}
int cellsize = Integer.parseInt(args[1]);
int borderwidth = Integer.parseInt(args[2]);
int sleeptime = Integer.parseInt(args[3]);
if (sleeptime < 0 || sleeptime > 10000) {
return false;
}
return true;
}
return false;
}
// Read the file describing the maze.
static char[][] readMazeFile(String mazefile) throws FileNotFoundException {
Scanner scanner = new Scanner(new File(mazefile));
height = scanner.nextInt();
width = scanner.nextInt();
int arrayHeight = 2 * height + 1;
int arrayWidth = 2 * width + 1;
char[][] mazeArrays = new char[arrayHeight][arrayWidth];
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
for (int row = 0; row < arrayHeight; row++) {
for (int col = 0; col < arrayWidth; col++) {
mazeArrays[row][col] = line.charAt(col);
}
}
}
return mazeArrays;
}
// Solve the maze.
static boolean solveMaze() {
return true;
}
}
I think I have the handling of command line arguments down. The readMazeFile method is where I'm currently struggling. I just can't wrap my head around storing the maze in an array and solving it.
Thanks!
The first thing to do is to work out a data structure for you to store the maze in. I suggest using a structure that makes the solving as easy as possible, even if printing is more complicated. Here is a simple example:
class Node {
private final int row;
private final int col;
private final List<Node> paths;
}
class Maze {
private final int rowCount;
private final int colCount;
private final List<Node> nodes;
private Node start;
private Node end;
}
This, in my view, is going to be more useful than something like an array. An array would make it easy to print the maze but that's not the most difficult part of the operation. A path finding algorithm needs to be able to easily get the paths from any position which this data structure allows.
You asked for some help on reading the maze. I suggest making the reading method a static 'builder' method inside Maze. In general the structure will be something like:
class Maze {
public static Maze buildMaze(String mazeFile) {
// read row & col size from file
Maze maze = new Maze(rows, cols);
// skip first line (invariant)
for (int row = 0; row < rows; row++) {
// get next 2 lines (for horizontal & vertical paths)
for (int col = 0; col < cols; col++) {
// get corresponding horizontal wall or space
if (isHorizontalPath) {
maze.getNode(row,col).addHorizontalPath();
}
if (hasVerticalPath) {
maze.getNode(row, col).addVerticalPath();
}
// check for S and E
if (isStart) {
maze.setStart(row, col);
} else if (isEnd) {
maze.setEnd(row, col);
}
}
}
return maze;
}
}
I have a question.
I have 10000 strings and I want to perform some operation on each of them. I would like to parallelize this operations in order to make the total execution time acceptable.
I decided to create the thread. In particular, every 10 strings I launch 10 threads. For every threads I save the result in a list.
I have tried two versions of my code. This is my first version.
int size = 10000;
int cont = 0;
int n = 1;
String[] arrstr2;
int threadgroup = 10;
if (cont + threadgroup - 1 > size) {
arrstr2[i - cont] = subject.toString();
} else {
arrstr2[i - cont] = subject.toString();
}
if ((i == (threadgroup * n) - 1) || (i == size - 1)) {
cont = i + 1;
n = n + 1;
for (int j = 0; j < arrstr2.length; j++) {
Thread t = new Thread(new MyThread(arrstr2[j], l));
t.start();
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (cont + threadgroup - 1 > size) {
arrstr2 = new String[size - i - 1];
}
}
i = i + 1;
In this version I don't get an advantages in the total execution.
This is my second version:
int size = 10000;
int cont = 0;
int n = 1;
String[] arrstr2;
int threadgroup = 10;
if (cont + threadgroup - 1 > size) {
arrstr2[i - cont] = subject.toString();
} else {
arrstr2[i - cont] = subject.toString();
}
if ((i == (threadgroup * n) - 1) || (i == size - 1)) {
cont = i + 1;
n = n + 1;
for (int j = 0; j < arrstr2.length; j++) {
Thread t = new Thread(new MyThread(arrstr2[j], l));
t.start();
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (cont + threadgroup - 1 > size) {
arrstr2 = new String[size - i - 1];
}
}
i = i + 1;
In this case I lose some information.
MyThread is a class that does some processing and puts the result in a list java:
public class MyThread implements Runnable{
String subject;
private List<String[]> l;
public MyThread(String subject, List<String[]> l) {
this.subject = subject;
this.l = l;
}
#Override
public void run() {
synchronized (l){
//do something
String[] result = new String[2];
result[0] = res0;
result[1] = res1;
l.add(result);
}
}
For my goal, this code is correct? How can I launch a group of thread in Java Code and to retrieve an acceptable time?
Here's a little example with an ExecutorService. The thread size is fixed to 10, but your can adjust it to your needs.
The StringTask basically reverses the given string.
public class Test {
private static final int THREADS = 10;
private static final int DATA_SIZE = 1000;
public static void main(String[] args) {
// Declare a new ExecutorService with a maximum of 2 threads.
ExecutorService service = Executors.newFixedThreadPool(THREADS);
// Prepare a list of Future results.
List<Future<String>> futures = new ArrayList<Future<String>>(DATA_SIZE);
// Submit the tasks and store the results.
for (int i = 0; i < DATA_SIZE; i++) {
futures.add(service.submit(new StringTask("Sample String " + i)));
}
// Accept no new tasks.
service.shutdown();
// Retrieve the actual String results.
List<String> results = new ArrayList<String>(DATA_SIZE);
try {
for (Future<String> future : futures) {
// The get() method blocks if the execution of the task is not finished.
results.add(future.get());
System.out.println(future.get());
}
} catch (ExecutionException ee) {
System.out.println("Error while getting result!");
ee.printStackTrace();
} catch (InterruptedException ie) {
System.out.println("Error while getting result!");
ie.printStackTrace();
}
}
/**
* Callable task that reverses a given String.
*/
private static final class StringTask implements Callable<String> {
private String input;
private StringTask(String input) {
super();
if (input == null) {
throw new NullPointerException();
}
this.input = input;
}
#Override
public String call() throws Exception {
StringBuilder builder = new StringBuilder();
for (int i = this.input.length() - 1; i >= 0; i--) {
builder.append(this.input.charAt(i));
}
return builder.toString();
}
}
}
I use a Callable here instead of a Runnable because the Callable allows the task to actually return a result that we can use (through the Future interface). If you only need a task executed, you can simply use a Runnable!
Maybe you might take a look at the new Java 8 Stream API.
http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
There you can easily parallelize such operations.
Using Java 8:
List<String> res = Arrays.toStream(arrstr2)
.parallel()
.map(s -> doWork(s))
.collect(Collectors.toList());