I'm trying to find how to collect averages of each field in a list of objects in one liner.
Here is what I'm trying to perform:
public class Value {
int a;
int b;
int c;
// rest of the class
}
Now let's assume I have List<Value> values = getMillionValues();
I know that to get average for one field, I can do following:
int averageOfA = values.stream().mapToInt(Value::getA).average()
What do I need to do in order to get averages for all values w/o repeating line above for each variable?
Maybe there are some other libraries, like Guava, that can help to perform these kind of operations?
Seriously, use a for loop.
int count = 0, sumA = 0, sumB = 0, sumC = 0;
for (Value v : values) {
sumA += v.getA();
sumB += v.getB();
sumC += v.getC();
count++;
}
double avgA = ((double) sumA) / count;
double avgB = ((double) sumB) / count;
double avgC = ((double) sumC) / count;
Seriously, use the code above.
Having said that you should use the code above, you can do it with a stream.
You need a few value holders (the average is a double, so your Value class can't store the averages):
class AveragesResult {
public final double a, b, c;
public AveragesResult(double a, double b, double c) {
this.a = a;
this.b = b;
this.c = c;
}
}
class AveragesIntermediate {
public final double a, b;
public AverageIntermediate(double a, double b) {
this.a = a;
this.b = b;
}
}
Now that we have the boilerplate out of the way (for good measure, you should implement hashCode, equals and toString, and add some getters), we can finally write the stream in a short and compact way:
values.stream().collect(teeing(
teeing(averagingInt(Value::getA), averagingInt(Value::getB), AveragesIntermediate::new),
averagingInt(Value::getC),
(ir, avgC) -> new AveragesResult(ir.a, ir.b, avgC));
Wasn't that hard, right? Make sure you have statically imported all the Collector functions (it looks a lot uglier with all those Collectors.) and you are using Java 12 (Collectors.teeing is new in Java 12).
Don't use that, use a good old for loop.
Related
how do I make my swap function in java if there is no method by which we can pass by reference? Could somebody give me a code?
swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
But the changes wont be reflected back since java passes parameters by value.
I think this is the closest you can get to a simple swap, but it does not have a straightforward usage pattern:
int swap(int a, int b) { // usage: y = swap(x, x=y);
return a;
}
y = swap(x, x=y);
It relies on the fact that x will pass into swap before y is assigned to x, then x is returned and assigned to y.
You can make it generic and swap any number of objects of the same type:
<T> T swap(T... args) { // usage: z = swap(a, a=b, b=c, ... y=z);
return args[0];
}
c = swap(a, a=b, b=c)
You can't create a method swap, so that after calling swap(x,y) the values of x and y will be swapped. You could create such a method for mutable classes by swapping their contents¹, but this would not change their object identity and you could not define a general method for this.
You can however write a method that swaps two items in an array or list if that's what you want.
¹ For example you could create a swap method that takes two lists and after executing the method, list x will have the previous contents of list y and list y will have the previous contents of list x.
It depends on what you want to do. This code swaps two elements of an array.
void swap(int i, int j, int[] arr) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
Something like this swaps the content of two int[] of equal length.
void swap(int[] arr1, int[] arr2) {
int[] t = arr1.clone();
System.arraycopy(arr2, 0, arr1, 0, t.length);
System.arraycopy(t, 0, arr2, 0, t.length);
}
Something like this swaps the content of two BitSet (using the XOR swap algorithm):
void swap(BitSet s1, BitSet s2) {
s1.xor(s2);
s2.xor(s1);
s1.xor(s2);
}
Something like this swaps the x and y fields of some Point class:
void swapXY(Point p) {
int t = p.x;
p.x = p.y;
p.y = t;
}
Apparently I don't have enough reputation points to comment on Dansalmo's
answer, but it is a good one, though mis-named. His answer is actually a K-combinator.
int K( int a, int b ) {
return a;
}
The JLS is specific about argument evaluation when passing to methods/ctors/etc. (Was this not so in older specs?)
Granted, this is a functional idiom, but it is clear enough to those who recognize it. (If you don't understand code you find, don't mess with it!)
y = K(x, x=y); // swap x and y
The K-combinator is specifically designed for this kind of thing. AFAIK there's no reason it shouldn't pass a code review.
My $0.02.
AFAIS, no one mentions of atomic reference.
Integer
public void swap(AtomicInteger a, AtomicInteger b){
a.set(b.getAndSet(a.get()));
}
String
public void swap(AtomicReference<String> a, AtomicReference<String> b){
a.set(b.getAndSet(a.get()));
}
As per #Stephan's comment: as long as you are not in a multi-threaded app, the following will work as well.
First: wrap your simple types in an array of size 1.
int[] x1 = {x};
int[] y1 = {y};
Then write a swap method
public void swap(int[] a, int[] b) {
assert(a.length == 1);
assert(b.length == 1);
int temp = a[0];
a[0] = b[0];
b[0] = temp;
}
If you want to make this work for all simple types, you'll have to write overloads, because Java Generics don't work for simple types.
I might do something like the following. Of course, with the wealth of Collection classes, i can't imagine ever needing to use this in any practical code.
public class Shift {
public static <T> T[] left (final T... i) {
if (1 >= i.length) {
return i;
}
final T t = i[0];
int x = 0;
for (; x < i.length - 1; x++) {
i[x] = i[x + 1];
}
i[x] = t;
return i;
}
}
Called with two arguments, it's a swap.
It can be used as follows:
int x = 1;
int y = 2;
Integer[] yx = Shift.left(x,y);
Alternatively:
Integer[] yx = {x,y};
Shift.left(yx);
Then
x = yx[0];
y = yx[1];
Note: it auto-boxes primitives.
Try this magic
public static <T> void swap(T a, T b) {
try {
Field[] fields = a.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object temp = field.get(a);
field.set(a, field.get(b));
field.set(b, temp);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
And test it!
System.out.println("a:" + a);
System.out.println("b:" + b);
swap(a,b);
System.out.println("a:" + a);
System.out.println("b:" + b);
For integer types, you can do
a ^= b;
b ^= a;
a ^= b;
using the bit-wise xor operator ^. As all the other suggestions, you probably shouldn't use it in production code.
For a reason I don't know, the single line version a ^= b ^= a ^= b doesn't work (maybe my Java compiler has a bug). The single line worked in C with all compilers I tried. However, two-line versions work:
a ^= b ^= a;
b ^= a;
as well as
b ^= a;
a ^= b ^= a;
A proof that it works: Let a₀ and b₀ be the initial values for a and b. After the first line, a is a₁ = a₀ xor b₀; after the second line, b is b₁ = b₀ xor a₁ = b₀ xor (a₀ xor b₀) = a₀. After the third line, a is a₂ = a₁ xor b₁ = a₁ xor (b₀ xor a₁) = b₀.
I'm working on this simple java recursion problem given the following directions:
Calculate the golden ratio.
Given two numbers a and b with a > b > 0, the ratio is b / a.
I have done some code but I'm stuck on getting the recursion working properly. Here's my code:
public class MyTesting {
public static void main(String[] args) {
System.out.println(ratio(8 , 4));
}
public static double ratio(int a, int b) {
int goldelRatio = 0;
if(a > b && b > 0){
return goldelRatio = a / b;
}
return goldelRatio;
}
}
How about something like this:
double goldenRatio(double a, double b, double epsilon) {
if(Math.abs((b / a) - ((a + b) / b)) < epsilon) {
return ((a + b) / b);
} else {
return goldenRatio(b, a + b, epsilon);
}
}
This way you achieve what you need in one function, with epsilon deciding how fine the resolution would be.
Also as an added bonus, and although Java doesn't have (at the time of writing this at least) tail recursion optimization, in theory this function could be optimized by tail recursion.
example with hard coded epsilon:
double goldenRatio(double a, double b) {
double epsilon = 0.00001;
if(Math.abs((b / a) - ((a + b) / b)) < epsilon) {
return ((a + b) / b);
} else {
return goldenRatio(b, a + b);
}
}
example run:
public static void main(String[] args) {
double goldenRation1 = goldenRatio(1.0, 1.0);
System.out.println(goldenRation1); // prints 1.618032786885246
System.out.println(goldenRation1 > 1.61800 && goldenRation1 < 1.61806); // prints true
double goldenRation2 = goldenRatio(100.0, 6.0);
System.out.println(goldenRation2); // prints 1.6180367504835589
System.out.println(goldenRation2 > 1.61800 && goldenRation2 < 1.61806); // prints true
}
Yours is not a recursive function, a recursive function that calculates Golden Ratio would look like the one below.
private int MAX_COUNTER = 50;
private int count = 0;
public double ratio(double a, double b) {
count++;
double goldenRatio = b / a;
if (count < MAX_COUNTER) {
return ratio(b, a + b);
}
return goldenRatio;
}
NOTE: I put the counters because given that is a recursive function trying to find a number with infinite decimals, it will cause the JVM to go on StackOverflow :) , so we got to stop it sooner or later.
Recursion mainly means methods calling themself, meaning you should try something like that:
public double recursionMethod(int a, int b){
int c = a+b;
if(Math.abs(ratio(b,a)-ratio(c,b))< (double) 1/42)
return ratio(c,b);
else
return recursionMethod(b,c);
}
1/42 is just your accuracy, you can implement any other breaking condition you like. Call this method in main with arguments (1,1).
I have created a class named Times and I have to construct 4 overloaded methods. I just would like some help understanding overloaded methods and at least maybe some help with the first one. I would really appreciate it. Thanks :)
multiply 2 integers and return the (integer) product
multiply 3 integers and return the (integer) product
multiply 2 double values and return the (double) product
multiply 3 double values and return the (double) product
like this?
public class Times {
public static int multiply(int a, int b) {
return a * b;
}
public static int multiply(int a, int b, in c) {
return multiply(a, b) * c;
}
public static double multiply(double a, double b) {
return a * b;
}
public static double multiply(double a, double b) {
return multiply(a, b) * c;
}
}
"Overloaded methods" just means the methods would all have the same name (and be in the same class). The parameters need to be different either in number or type, however.
Since the all multiply stuff, "multiply" makes sense as a name.
The first one:
multiply 2 integers and return the
(integer) product
So it returns an integer (an int), is named "multiply", takes 2 ints as parameters, that gives us:
int multiply(int a, int b) {
It returns the product, so the body is:
return a * b;
And then we're done with that one:
}
That gives us:
int multiply(int a, int b) {
return a * b;
}
Use the same approach and the same name for the others.
it would look somthing like this :
public class Times {
public int mult(int a, int b) {
return a*b;
}
public int mult(int a, int b, int c) {
return a*b*c;
}
//2 more overloaded versions to come here
}
as for understanding what they mean - when your code is compiled the compiler determines which of the methods (all called the same name) to use by looking at the arguments.
so for instance for something like this
int a = 1;
int b = 1;
Times t = new Times();
t.mult(a,b);
the compiler will pick the 1st of the 2 mult methods i demonstrated, while for this:
int a = 1;
int b = 1;
int c = 2;
Times t = new Times();
t.mult(a,b,c);
it will pick the 2nd (based on the number of arguments)
You can do something like this
public class Times {
public static void main(String[] args) {
System.out.println(multiplyInt(1,2));
System.out.println(multiplyDoubles(2.0,3.0));
}
public static int multiplyInt(int... numbers){
int multiply = 1;
for(int number : numbers ){
multiply = multiply*number;
}
return multiply;
}
public static double multiplyDoubles(double... numbers){
double multiply = 1;
for(double number : numbers ){
multiply = multiply*number;
}
return multiply;
}
}
how do I make my swap function in java if there is no method by which we can pass by reference? Could somebody give me a code?
swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
But the changes wont be reflected back since java passes parameters by value.
I think this is the closest you can get to a simple swap, but it does not have a straightforward usage pattern:
int swap(int a, int b) { // usage: y = swap(x, x=y);
return a;
}
y = swap(x, x=y);
It relies on the fact that x will pass into swap before y is assigned to x, then x is returned and assigned to y.
You can make it generic and swap any number of objects of the same type:
<T> T swap(T... args) { // usage: z = swap(a, a=b, b=c, ... y=z);
return args[0];
}
c = swap(a, a=b, b=c)
You can't create a method swap, so that after calling swap(x,y) the values of x and y will be swapped. You could create such a method for mutable classes by swapping their contents¹, but this would not change their object identity and you could not define a general method for this.
You can however write a method that swaps two items in an array or list if that's what you want.
¹ For example you could create a swap method that takes two lists and after executing the method, list x will have the previous contents of list y and list y will have the previous contents of list x.
It depends on what you want to do. This code swaps two elements of an array.
void swap(int i, int j, int[] arr) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
Something like this swaps the content of two int[] of equal length.
void swap(int[] arr1, int[] arr2) {
int[] t = arr1.clone();
System.arraycopy(arr2, 0, arr1, 0, t.length);
System.arraycopy(t, 0, arr2, 0, t.length);
}
Something like this swaps the content of two BitSet (using the XOR swap algorithm):
void swap(BitSet s1, BitSet s2) {
s1.xor(s2);
s2.xor(s1);
s1.xor(s2);
}
Something like this swaps the x and y fields of some Point class:
void swapXY(Point p) {
int t = p.x;
p.x = p.y;
p.y = t;
}
Apparently I don't have enough reputation points to comment on Dansalmo's
answer, but it is a good one, though mis-named. His answer is actually a K-combinator.
int K( int a, int b ) {
return a;
}
The JLS is specific about argument evaluation when passing to methods/ctors/etc. (Was this not so in older specs?)
Granted, this is a functional idiom, but it is clear enough to those who recognize it. (If you don't understand code you find, don't mess with it!)
y = K(x, x=y); // swap x and y
The K-combinator is specifically designed for this kind of thing. AFAIK there's no reason it shouldn't pass a code review.
My $0.02.
AFAIS, no one mentions of atomic reference.
Integer
public void swap(AtomicInteger a, AtomicInteger b){
a.set(b.getAndSet(a.get()));
}
String
public void swap(AtomicReference<String> a, AtomicReference<String> b){
a.set(b.getAndSet(a.get()));
}
As per #Stephan's comment: as long as you are not in a multi-threaded app, the following will work as well.
First: wrap your simple types in an array of size 1.
int[] x1 = {x};
int[] y1 = {y};
Then write a swap method
public void swap(int[] a, int[] b) {
assert(a.length == 1);
assert(b.length == 1);
int temp = a[0];
a[0] = b[0];
b[0] = temp;
}
If you want to make this work for all simple types, you'll have to write overloads, because Java Generics don't work for simple types.
I might do something like the following. Of course, with the wealth of Collection classes, i can't imagine ever needing to use this in any practical code.
public class Shift {
public static <T> T[] left (final T... i) {
if (1 >= i.length) {
return i;
}
final T t = i[0];
int x = 0;
for (; x < i.length - 1; x++) {
i[x] = i[x + 1];
}
i[x] = t;
return i;
}
}
Called with two arguments, it's a swap.
It can be used as follows:
int x = 1;
int y = 2;
Integer[] yx = Shift.left(x,y);
Alternatively:
Integer[] yx = {x,y};
Shift.left(yx);
Then
x = yx[0];
y = yx[1];
Note: it auto-boxes primitives.
Try this magic
public static <T> void swap(T a, T b) {
try {
Field[] fields = a.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object temp = field.get(a);
field.set(a, field.get(b));
field.set(b, temp);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
And test it!
System.out.println("a:" + a);
System.out.println("b:" + b);
swap(a,b);
System.out.println("a:" + a);
System.out.println("b:" + b);
For integer types, you can do
a ^= b;
b ^= a;
a ^= b;
using the bit-wise xor operator ^. As all the other suggestions, you probably shouldn't use it in production code.
For a reason I don't know, the single line version a ^= b ^= a ^= b doesn't work (maybe my Java compiler has a bug). The single line worked in C with all compilers I tried. However, two-line versions work:
a ^= b ^= a;
b ^= a;
as well as
b ^= a;
a ^= b ^= a;
A proof that it works: Let a₀ and b₀ be the initial values for a and b. After the first line, a is a₁ = a₀ xor b₀; after the second line, b is b₁ = b₀ xor a₁ = b₀ xor (a₀ xor b₀) = a₀. After the third line, a is a₂ = a₁ xor b₁ = a₁ xor (b₀ xor a₁) = b₀.
I really suck at math. I mean, I REALLY suck at math.
I'm trying to make a simple fibonacci sequence class for an algorithm I'll be using. I have seen the python example which looks something like this:
a = 0
b = 1
while b < 10:
print b
a, b = b, b+a
The problem is that I can't really make this work in any other language. I'd like to make it work in Java, since I can pretty much translate it into the other languages I use from there. This is the general thought:
public class FibonacciAlgorithm {
private Integer a = 0;
private Integer b = 1;
public FibonacciAlgorithm() {
}
public Integer increment() {
a = b;
b = a + b;
return value;
}
public Integer getValue() {
return b;
}
}
All that I end up with is doubling, which I could do with multiplication :(
Can anyone help me out? Math pwns me.
I'd do it this way:
public class FibonacciAlgorithm {
private int a = 0;
private int b = 1;
public FibonacciAlgorithm() {
}
public int increment() {
int temp = b;
b = a + b;
a = temp;
return value;
}
public int getValue() {
return b;
}
}
This keeps it as close to your original Java code as possible.
[Editor's note: Integers have been replaced with ints. There is no reason to use Integers for this.]
The line
a, b = b, b+a
Doesn't easily translate. It's something like this. You could simplify it. This is the literal meaning.
t1 = b
t2 = b+a
a = t1
b = t2
You need to store the value of either a or b in a temporary variable first;
public Integer increment()
{
int temp = a;
a = b;
b = temp + b;
return value;
}
Java integers can only store the first 46 Fibonacci numbers, use a lookup table.
I'll just translate your earlier code:
public void fibb(int max) {
int a = 0;
int b = 1;
while (a < max) {
System.out.println(a);
int temp = a + b;
a = b;
b = temp;
}
}
Don't you want to create a function to return the nth Fibnoacci number? This is how I remember it being taught when I was a kid:
public int Fibb(int index) {
if (index < 2)
return 1;
else
return Fibb(index-1)+Fibb(index-2);
};
Given the definition being the first pair of Fibbonaci numbers are 1 and everything else is based off of that. Now, if you merely want to print out the Fibonaccis a loop may be simpler which is what a lot of the other replies cover.
The main problem with your Python-to-Java translation is that Python's assignment statement up there is executed all at once, while Java's are executed serially. Python's statement is equivalent to saying this:
Make a list out of 'b' and 'a + b'
Make another list out of references to 'a' and 'b'
Assign all the elements from the second list to the first one
(It might actually be a tuple, I'm not exactly fluent in Python.)
So the 'b' and 'a+b' resolve to values before they are assigned. You can't do that kind of multiple-simultaneous assignment in Java.
In general, a statement in Python like
var1, var2, ...varN = expression1, expression2, ...expressionN
is going to translate in Java to
temp1 = expression1;
temp2 = expression2;
...
tempN = expressionN;
var1 = temp1;
var2 = temp2;
...
varN = tempN;
This way all the expressions resolve to values before the assignments happen, and none of the assignments have side effects on the expressions.
If I were doing this for real I'd probably do the lookup table and store longs (since Fibonacci numbers grow vaguely exponentially and I'd want to go past 46). The iterative form, like you have, will take O(N) to calculate the Nth Fibonacci value; the typical recursive formulation will take as many function calls as the returned value. Fibonacci practically begs for the answers to be cached somewhere, and this would make the recursive form much more feasible.
There was a recursive solution posted above, but this solution is tail recursive so it grows linearly.
public class Fibonacci {
public long fibonacci(int number) {
return fib(0,1,number);
}
private long fib(long result, long next, int n) {
if (n == 0)
return result;
else
return fib(next, result+next, n-1);
}
}
i'll do this
fib = 100;
for(int a = 1, b = 0;a <= fib;a += b, b = (a-b)) {
System.out.print(a + ",");
}
public Integer increment() {
a = b;
b = a + b;
return value;
}
Is certainly wrong. I think switching the first two lines should do the trick