hashmap is different outside of while loop - java

I'm not sure why the hashmap is printing out different things inside this while loop and outside of the while loop. I declared the map outside the while loop, so I assumed that it should be the same inside and outside. In the code, I have the same print statement inside the while loop and outside of it, but they are printing different things. The key for the map is personCounter, which increments and should be unique. Would really appreciate your help.
public Map<Integer, double[]> setRating(CSVReader r, int taskNum, int taskWeightNumHeader)
throws NumberFormatException, IOException {
String[] line;
int personCounter = 0;
Map<Integer, double[]> indivTaskRating = new HashMap<Integer, double[]>();
while ((line = r.readNext()) != null) {
double[] perTaskWeight = new double[5];
personCounter++;
int multiplier = taskNum * 5;
perTaskWeight[2] = Double.parseDouble(line[taskWeightNumHeader + multiplier]);
perTaskWeight[1] = Double.parseDouble(line[taskWeightNumHeader + multiplier + 1]);
perTaskWeight[0] = Double.parseDouble(line[taskWeightNumHeader + multiplier + 2]);
perTaskWeight[3] = Double.parseDouble(line[taskWeightNumHeader + multiplier + 3]);
perTaskWeight[4] = Double.parseDouble(line[taskWeightNumHeader + multiplier + 4]);
indivTaskRating.put(personCounter, perTaskWeight);
for (int j = 0; j < 5; j ++) {
System.out.println("personID: " +1+ ", rating: " +indivTaskRating.get(1)[j]);
}
}
for (int j = 0; j < 5; j ++) {
System.out.println("personID: " + 1+ ", rating: " +indivTaskRating.get(1)[j]);
}
return indivTaskRating;
}

You are using the same double array in every entry you place in the map. At the end it will be populated with the same values for each entry!
You need to reallocate the array on each iteration of your while loop to fix the problem.
while ((line = r.readNext()) != null) {
double[] perTaskWeight = new double[5];
// ....
}

You keep reusing the same array, so you actually overwrite its content at each loop (while).
You need to create a new instance (double[] perTaskWeight = new double[5];) within the while loop.

Related

Basic counter arraylist in method java

I am trying to make a counter with a list of 10 elements in random position, the problem is that after making the complete tour of my array I must print on the screen how many numbers that are repeated.
To do this, I made the method out of my Main space, I declared the array and the "for loop" to tour my array, the question is after that I must will include in the same method the counter ? ...
public static int Vectores(int a[]) {
// Declared variable
a = new int[10];
int lf = a.length;
// Here we will tour the array and then complete the arrays with random numbers.
for (int i = 0; i < lf; i++) {
a[i] = (int) (Math.random() * 100);
System.out.println(" A:" + a[i] );
}
return a[i];
// Here will be an "if condition" + and for loop to the counter
int counter = 0;
for (int i = 0; i < 10; i++) {
}
} // END
Your method is taking an array as param, which is being assigned with a new array and the array itself not return. If the random values have to be generated in the method and only the number of repetitions needed, the parameter is not needed! And you also have a return statement after your first loop, making the rest of the code unreachable!
This being said, you could track the repetitions as follow:
...
int a[] = new int[10];
Map<Integer, Integer> count = new HashMap<>();
for (int i = 0; i < a.length; i++) {
a[i] = (int) (Math.random() * 10);
count.compute(a[i], (k, ov) -> ov != null ? ++ov : 1);
}
List<Entry<Integer, Integer>> repetitions = count.entrySet().stream()
.filter(e -> e.getValue() > 1)
.collect(Collectors.toList());
// Return the value & or display the details
if (repetitions.isEmpty()) {
System.out.println("No repetition found !");
} else {
System.out.println("Number of value which are repeated : " + repetitions.size());
repetitions.forEach(e -> System.out.println(e.getKey() + " -> " + e.getValue() + " times"));
}
...
Cheers!

Java Array plus 1

my java code needs to plus 1 and im getting an error saying
ArrayTask3.java:8: error: incompatible types: int cannot be converted to int[]
int[] row = intList [i];
It should just read my array and then add 1 to each number. could someone please help me get it to work correctly.
class ArrayTask3 {
public static void main(String[] args) {
int [] intList = {5,20,32,7,9};
int sum = 0;
for (int i = intList.length-1; i >=0; i--) {
int[] row = intList [i];
for (int j = 0; j < row.length; j++) {
row[j] = row[j] + 1;
}
System.out.println ("intList [" + i + "]: " + intList [i]);
}
for (int counter=0;counter<intList.length;counter++)
sum = sum + intList[counter];
System.out.println ("Sum = " + sum);
}
}
intList is just a int[], not a 2-d array. Instead of making a new array called "row" in your for loop, you can simply do intList[i]++.
(intList[i]++ and intList[i] = intList[i] + 1 and intList[i] += 1 are the same)
for (int i = 0; i < intList.length; i++) {
intList[i]++;
System.out.println ("intList [" + i + "]: " + intList [i]);
}
Also, it's more normal to make your for loop be
for (int i = 0; i < someArray.length; i++) {
//code
}
instead of what you did, which is
for (int i = someArray.length-1; i >= 0; i--) {
//code
}
Both of these do the exact same thing, but the first option is more "normal" and easier to read.
The issue there was that you are setting an int array equal to an int ( not an array element equal to an int ). I fixed the code for you:
class ArrayTask3 {
public static void main(String[] args) {
int [] intList = {5,20,32,7,9};
int sum = 0;
for (int i = intList.length-1; i >=0; i--) {
// you can directly set the element using this
intList[i] = intList[i]+1;
System.out.println ("intList [" + i + "]: " + intList [i]);
}
for (int counter=0;counter<intList.length;counter++)
sum = sum + intList[counter];
System.out.println ("Sum = " + sum);
}
}
intList is a single dimensional array so intList[i] is the int at position i in intList. I think what you want to do is increase the integer by one or intList[i]++; or intList[i] += 1;.
You are currently trying to loop through a 2-dimensional array or matrix by selecting rows. In which case you would need to define intList as an int[][] or an array of integer arrays.
for (int i = intList.length-1; i >=0; i--) {
/**
* I am not sure on what you want to do with this line.
* You can't assign an integer to array without reference
* If you want to copy the value of intList to row you can use int[] row = intList;
*/
int[] row = intList [i];
for (int j = 0; j < row.length; j++) {
row[j] = row[j] + 1;
}
System.out.println ("intList [" + i + "]: " + intList [i]);
}
Try using below code. It adds 1 to each number and prints the sum of all numbers at the end.
public static void main(String[] args) {
int[] intList = { 5, 20, 32, 7, 9 };
int sum = 0;
for (int i = 0; i < intList.length; i++) {
intList[i]++;
System.out.println("intList [" + i + "]: " + intList[i]);
sum += intList[i];
}
System.out.println(sum);
}

java read csv + specific sum of subarray - most efficient way

I need to read ints from large csv and then do specific sums with them. Currently I have algorithm that:
String csvFile = "D:/input.csv";
String line = "";
String cvsSplitBy = ";";
Vector<Int[]> converted = new Vector<Int[]>();
try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
while ((line = br.readLine()) != null) {
String[] a = line.split(";",-1);
int[] b = new int[a.length];
for (int n = 0, n < a.length(), n++){
b[n] = Integer.parseInt(a[n]);
}
converted.add(b);
}
}
catch (IOException e) {
e.printStackTrace();
}
int x = 7;
int y = 5;
int sum = 0;
for (int m = 0; m < converted.size(); m++){
for (n = 0, n < x, n++){
sum = sum + converted.get(m)[n];
}
System.out.print(sum + " ");
for (int n = x + y, n < converted.get(m).length, n = n + y){
sum = 0;
for (int o = n -y; o < n; o++)
sum = sum + converted.get(m)[n];
}
System.out.print(sum + " ");
}
System.out.println("");
}
What I tried to do, is to get sum of first x members of a csv row, and then sum of x members every +y. (in this case sum of first x - 7(sum of 0-6), then sum of next x - 7, but y - 5 columns later(sum of 5-11), (sum of 10-16)... and write them, for every row.(in the end collecting line number with greatest (sum of 0-6), (sum of 5-11).., so final result should be for example 5,9,13,155..., which would mean line 5 had the greatest sum of 0-6, line 9 greatest sum of 5-11... ) As you can see, this is a quite inefficient way. First I've read whole csv into string[], then to int[] and saved to Vector. Then I created quite inefficient loop to do the work. I need this to run as fast as possible, as i will be using very large csv with lot of different x and y. What I was thinking about, but don't know how to do it is:
do these sums in the reading loop
do the sum differently, not always looping x members backward (either saving last sum and then subtract old and add new members, or other faster way to do subarray sum)
use intStream and parallelism (parallel might be tricky as in the end i am looking for max )
use different input then csv?
all of the above?
How can I do this as fast as possible? Thank you
As the sums are per line, you do not need to first read all in memory.
Path csvFile = Paths.get("D:/input.csv");
try (BufferedReader br = Files.newBufferedReader(csvFile, StandardCharsets.ISO_8859_1)) {
String line;
while ((line = br.readLine()) != null) {
int[] b = lineToInts(line);
int n = b.length;
// Sum while reading:
int sum = 0;
for (int i = 0; i < 7; ++i) {
sum += b[i];
}
System.out.print(sum + " ");
sum = 0;
for (int i = n - 5; i < n; ++i) {
sum += b[i];
}
System.out.print(sum + " ");
System.out.println();
}
}
private static int[] lineToInts(String line) {
// Using split is slow, one could optimize the implementation.
String[] a = line.split(";", -1);
int[] b = new int[a.length];
for (int n = 0, n < a.length(), n++){
b[n] = Integer.parseInt(a[n]);
}
return b;
}
A faster version:
private static int[] lineToInts(String line) {
int semicolons = 0;
for (int i = 0; (i = line.indexOf(';', i)) != -1; ++i) {
++semicolons;
}
int[] b = new int[semicolons + 1];
int pos = 0;
for (int i = 0; i < b.length(); ++i) {
int pos2 = line.indexOf(';', pos);
if (pos2 < 0) {
pos2 = line.length();
}
b[i] = Integer.parseInt(line.substring(pos, pos2));
pos = pos2 + 1;
}
return b;
}
As an aside: Vector is old, better use List and ArrayList.
List<int[]> converted = new ArrayList<>(10_000);
Above the optional argument of initial capacity is given: ten thousand.
The weird try-with-resource syntax try (BufferedReader br = ...) { ensures that br is alway automatically closed. Even on exception or return.
Parallelism and after reformatting the question
You could read all lines
List<String> lines = Files.readAllLines(csvFile, StandardCharsets.ISO_8859_1);
And than play with parallel streams like:
OptionalInt max = lines.parallelStream()
.mapToInt(line -> {
int[] b = lineToInst(line);
...
return sum;
}).max();
or:
IntStream.range(0, lines.size()).parallel()
.mapToObj(i -> {
String line = lines.get(i);
...
return new int[] { i, sum5, sum7 };
});
You could probably try to create some of your sums while reading the input. Might also be feasible to use HashMaps of type Integer,Integer

Array Out of Bound Index Error

I am attempting to find the occurrence frequency of a number in a sequence.
for example when sequence is :
1, 1, 3, 4
output should be
1 found 3 times
, 3 found 1 times
, 4 found 1 time
and so on. I have the following code
import java.util.*;
class fre {
public static void main(String a[]) {
int c = a.length;
int d[] = new int[c];
int num = 0;
for (int p = 0; p < c; p++)
d[p] = Integer.parseInt(a[p]);
for (int z : d)
System.out.println(z);
for (int i = 0; i < c - 1; i++) // FROM THIS LINE ERROR IS THROWN
{
for (int t = 0; t < c - 1; i++) {
if (d[i] == d[t]) {
num++;
}
}
System.out.println("the element" + i + "found" + num + "times");
}
}
}
ERROR : ARRAY OUT OF BOUND INDEX
Shouldn't
for (int t = 0; t < c - 1; i++)
be
for (int t = 0; t < c - 1; t++)
You are incrementing i again in the second loop.
Well, first of all, you increment i instead of t in the inner loop.
Changing this, the program seems to work.
Change the output line to sth. like
System.out.println("the element " + d[i] + " found " + num + " times");
To make it readable.
Not saying there is no better way to solve this...
ok
Benno
a is an array that holds all the command line parameters. You are using a.length which determines the amount of command line parameters given. I guess you probably want to pass the length of the array by a command line parameter instead. If I am correct, you should use something like int c = a[0]; to get the first command line parameter. Of course that is not good style without any checks, but if I get started on that I had to rewrite your whole code ;)
Your example is wrong.
Untested:
public static void main(String args[])
{
Map<Integer, Integer> result = new HashMap<>();
for (String s : args) {
Integer currentNumber = Integer.parseInt(s);
// don't forget error handling if s is not a number
Integer currentCount = result.get(currentNumber);
if (currentCount == null) { // you could also check with result.containsKey(..)
currentCount = 0;
}
result.put(currentNumber, currentCount + 1);
}
for (Map.Entry<Integer, Integer> entry : result) {
System.out.println("The element: " + entry.getKey() + " found " + entry.getValue() + " times");
}
}
This is probably slower than your version, but easier to understand.

Arrays (toString) not output correctly

Actually this tread is continuing from the other one. There wasn't enough characters to continue there. Anyway. the problem is that the output is "1(10) 2(23) 3(29)". Even though I could return string for the array values (10,23,29) and used string reference as 1, 2 and 3. My question is it possible to return index values 1,2,3 and as well as array values. Am I making an sense. Here is what I have done...
// int[] groups = {10, 23, 29}; in the constructor
String tempA = "";
String tempB = " ";
int[] temp = new int[4];
int length = groups.length;
for (int j = 0; j < length; j++)
{
temp[j] = groups[j];
tempB = tempB + "("+goups+")";
}
groups = temp;
Arrays.sort(coingroups);
for(int i = 1; i < groups.length;i++)
{
tempA = tempA+" "+(i)+ "("+groups[i]+")";
}
return tempA;
With the below code you are creating a string that and this string represents the whole array. Yet it will be harder to work with then just using the array 'groups'
// int[] groups = {10, 23, 29}; in the constructor
String tempA = "";
for (int j = 0; j < groups.length; j++)
{
tempA = tempA + " " + j + " (" + groups[j] + ") ";
}
return tempA;
If you create a Map, and save your data in there, you can get any information you want. Like:
Map<Integer, String> stack = new HashMap<Integer, String>();
stack.put(1, "10");
stack.put(2, "23");
stack.put(3, "29");
After storing everything, you can get the values of the Map by its key or value. Example:
stack.get(1) will return "10"
stack.get("10") will return 1

Categories

Resources