Is there a way to combine the following 2 Statesments?
Map<Integer,Double> collX = listeAllerPunkte.stream().collect(groupingBy(DataPoint::getId,
averagingDouble(DataPoint::getX)));
Map<Integer,Double> collY = listeAllerPunkte.stream().collect(groupingBy(DataPoint::getId,
averagingDouble(DataPoint::getY)));
I have a Class DataPoints like this:
public class DataPoint {
public final double x;
public final double y;
private int Id;
public DataPoint(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public int getId() {
return Id;
}
}
The Id contains a Random value between 0-5.
listeAllerPunkte is a List with a lot of DataPoints
Now I want to create a DataPoint for each DataPoints in the List with the same Id. The DataPoint should have the average of the x and y values of the Datapoints with the same Id.
With the two Statemantes from the Beginning i must create the DataPoints manually out of the two Maps.
Is there a way to create them directly in the stream?
A general solution would be using a collector which can combine two collectors to process both at once. Unfortunately, such collector does not exist in the standard API, but this answer provide an implementation of such a collector.
Alternatively, you can create a solution for this specific case by creating your own class for holding the summary of points, e.g.
static class DataPointSummary {
long count;
double sumX, sumY;
public double getAverageX() {
return count==0? 0: sumX/count;
}
public double getAverageY() {
return count==0? 0: sumY/count;
}
public void add(DataPoint p) {
count++;
sumX+=p.getX();
sumY+=p.getY();
}
public DataPointSummary merge(DataPointSummary s) {
count+=s.count;
sumX+=s.sumX;
sumY+=s.sumY;
return this;
}
#Override
public String toString() {
return "DataPointSummary["+count+" points"
+", avg x="+getAverageX()+", avg y="+getAverageY()+']';
}
}
Then you may collect your points like
Map<Integer,DataPointSummary> coll = listeAllerPunkte.stream().collect(
groupingBy(DataPoint::getId, Collector.of(
DataPointSummary::new, DataPointSummary::add, DataPointSummary::merge)));
Note that I assumed that you method signature public double getId() is a typo and actually public int getId() as otherwise, the examples in your question won’t work.
The summary implementation above works well if the coordinates of the points have the same magnitude. If you encounter both, very large values and very small values within the same group, you may need a summing with error compensation algorithm. Instead of implementing it yourself, I recommend using the summary implementation of the JRE instead:
static class DataPointSummary {
final DoubleSummaryStatistics x=new DoubleSummaryStatistics();
final DoubleSummaryStatistics y=new DoubleSummaryStatistics();
public double getAverageX() {
return x.getAverage();
}
public double getAverageY() {
return y.getAverage();
}
public void add(DataPoint p) {
x.accept(p.getX());
y.accept(p.getY());
}
public DataPointSummary merge(DataPointSummary s) {
x.combine(s.x);
y.combine(s.y);
return this;
}
#Override
public String toString() {
return "DataPointSummary["+x.getCount()+" points"
+", avg x="+getAverageX()+", avg y="+getAverageY()+']';
}
}
This variant is used the same way as the first one.
Related
I'm coding something for a theoretical airport case study and I need help with one bit. I've got 2 different integers with names: maxfuelCapacity and fuelCurrent, and I need something that says ' fuel needed to pump is '.....' being the difference between the maxfuelCapacity of the plane and the current amount. There are no real values so far. How do I go about doing that?
public static int maxfuelCapacity;
public int fuelCurrent;
public String name;
Boolean parked;
public String[] Plane = {
"BA103", "BA493", "BA209"
};
public void setName(String n) {
name = n;
}
public void setParked(Boolean o) {
parked = o;
}
public int getInt(String Maxfuelcapacity) {
return maxfuelCapacity;
}
public String getInt1 (String fuelCurrent) {
return fuelCurrent;
}
As has been mentioned in the comments, your method would look like:
public int fuelNeeded(int fuelCurrent, int maxfuelCapacity) {
if(fuelCurrent >= maxfuelCapacity) {
System.out.println("The tank already has enough");
return 0;
}
return maxfuelCapacity- fuelCurrent;
}
So you call this method in your main function that does the calculation.
After researching a little bit, I couldn't figure out how to create a obj1 distance to be able to compare with obj2. All these methods were given in assessment I had so, no chance to change logic of it. I suppose to return 3 Strings answer depending of the data. Thanks a lot in advance guys. I've attached a pease of pic.
enter image description here
public class Main {
public static void main(String[] args) {
Distance dist1 = new DistanceImplementation();
Distance obj2 = new DistanceImplementation();
dist1.setFeetAndInches(1, 8);
obj2.setFeetAndInches(3, 5);
System.out.println(dist1.getDistanceComparison(obj2));
}
}
public abstract class Distance {
protected int feet;
protected float inches;
abstract public void setFeetAndInches(int feet, float inches);
abstract public int getFeet();
abstract public float getInches();
abstract String getDistanceComparison(Distance dist2);
}
class DistanceImplementation extends Distance {
#Override
public void setFeetAndInches(int feet, float inches) {
this.feet = feet;
this.inches = inches;
}
#Override
public int getFeet() {
return this.feet;
}
#Override
public float getInches() {
return this.inches;
}
#Override
String getDistanceComparison(Distance dist2) {
// if (dist2) { ????????????
return null;
}
}
Well, after reading the assessment, I think that you can safely assume that 1 foot = 12 inches. So, in order to correctly implement the getDistanceComparison method, you could calculate the total distance in inches for both the current object and the parameter, compare them and then return the corresponding string value.
Suppose you have the following method:
private float getTotalInches() {
return (float) feet * 12.0 + inches;
}
This method returns the total inches of this DistanceImplementation instance, taking into account the feet and the inches attributes.
Please note that for the total result to be of type float, we need to first cast the feet attribute to float, so that it actually becomes of type float. Then, we multiply by 12.0 (note the .0, it's important because it indicates that the 12.0 literal value is also a float). Then, we are summing two float values, which yields a result of type float. While all this casting and convertions are not always necessary (sometimes the compiler is smart enough as to guess the correct types and preserve decimal precision), it's considred good practice to make your intentions crystal-clear, so that future developers that will maintain your code know what you have tried to accomplish.
Then, once you have this method, it would be easy to compare the total inches of both DistanceImplementation instances and return the corresponding string:
#Override
String getDistanceComparison(Distance dist2) {
float myTotalInches = getTotalInches();
float otherTotalInches = dist2.getTotalInches();
if (myTotalInches > otherTotalInches) {
// return ...
} else if (myTotalInches < otherTotalInches) {
// return ...
} else {
// return ...
}
}
Here is the solution on which I was working and it might be useful as well
package com.prog;
import java.util.Scanner;
abstract class Distance {
protected int feet;
protected float inches;
abstract public void setFeetAndInches(int feet, float inches);
abstract public int getFeet();
abstract public float getInches();
abstract String getDistanceComparison(Distance dist2);
}
public class DistanceCalculator {
private static final Scanner scan = new Scanner(System.in);
public static void main(String[] args) {
Distance dist1 = new DistanceImplementation();
Distance dist2 = new DistanceImplementation();
int feet1 = 1;
float inches1 = (float) 2.0;
int feet2 = 3;
float inches2 = (float) 4.1;
dist1.setFeetAndInches(feet1, inches1);
dist2.setFeetAndInches(feet2, inches2);
System.out.println(dist1.getDistanceComparison(dist2));
}
}
package com.prog;
public class DistanceImplementation extends Distance {
#Override
public void setFeetAndInches(int feet, float inches) {
this.feet=(int) (feet+ (inches/12));
this.inches=inches+ (feet*12);
}
#Override
public int getFeet() {
return feet;
}
#Override
public float getInches() {
return inches;
}
#Override
String getDistanceComparison(Distance dist2) {
String ret;
int dist1a=this.getFeet();
System.out.println(dist1a);
int dist2a=dist2.getFeet();
if(dist1a > dist2a)
return "First is greater";
else if(dist1a < dist2a)
return "Second is greater";
else
return "Both are equal";
}
}
I am trying to create a method for " winning percentage " in a player class. I know I need to incorporate total wins divided by total games played, but the code is meant to be simple so I cannot use complex code. (beginner project in computer science) Any useful feedback would be great as I have spent multiple days attempting this and getting no where. By the way, ties count as half a win.
Update: Implemented the getters into the getWinningPercentage method. Also calculated everything inside the getWinningPercentage and removed the setWinningPercentage considering it was useless code. Results were as follows:
Bob
5 wins, 1 losses, 2 ties
Winning percentage = 0.75
public class Player
{
private int numWins = 0;
private int numTies = 0;
private int numLosses = 0;
private String name;
public void setWins(int w)
{
numWins = w;
}
public int getWins()
{
return numWins;
}
public void setTies(int t)
{
numTies = t;
}
public int getTies()
{
return numTies;
}
public void setLosses(int L)
{
numLosses = L;
}
public int getLosses()
{
return numLosses;
}
public void setName(String n)
{
name = n;
}
public String getName()
{
return name;
}
public void incrementWins()
}
numWins++;
}
public void incrementTies()
{
numTies++;
}
public void incrementLosses()
{
numLosses++;
}
public double getWinningPercentage()
{
double totalGames = getWins() + getTies() + getLosses();
double totalWins = getWins() + (getTies() / 2.0);
double winningPercentage = (totalWins / totalGames);
return winningPercentage;
}
}
The winning percentage should be a calculated property, not a field, and not have a setter method. Instead there should only be a "getter" (public double getWinningPercentage()) method and you should calculate and return this value from within the method itself from the other fields that your class already has.
We should leave it up to you to create this method and formula yourself.
Say that I have this class:
public class Bucket<T> {
T filling;
}
and the filling attribute can be an instance of either one of these:
public class Oil{
float volume;
}
or
public class Water{
float volume;
}
In one part of my code, I have a list of Buckets:
LinkedList<Bucket> list;
Now, I want to order the elements of "list"(Bucket) by the attribute "volume".
But I can't compare T.volume. So, how do I do that?
Sorry in advance if my question is stupid, I'm still learning java.
I answer you assuming this is a theoritical question, I do not advise you to implement that but to find a better pattern to do what you want.
You want to sort a List of Bucket. To call Collections.sort() method, Bucket needs to implements Comparable (and so to define compareTo method).
You should define an interface implemented by your "filling" elements
interface Element {
float getVolume();
void setVolume(float volume);
}
class Oil implements Element {
float volume;
#Override
public float getVolume() {
return volume;
}
#Override
public void setVolume(float volume) {
this.volume = volume;
}
}
class Water implements Element {
float volume;
#Override
public float getVolume() {
return volume;
}
#Override
public void setVolume(float volume) {
this.volume = volume;
}
}
Now you can define Bucket class:
class Bucket implements Comparable<Bucket> {
Element filling;
#Override
public int compareTo(Bucket o) {
return Float.compare(filling.getVolume(), o.filling.getVolume());
}
}
And this code:
public static void main(String[] args) {
List<Bucket> elems = new LinkedList<>();
Bucket o = new Bucket();
o.filling = new Oil();
o.filling.setVolume(5);
Bucket w = new Bucket();
w.filling = new Water();
w.filling.setVolume(12);
elems.add(w);
elems.add(o);
Collections.sort(elems);
for(Bucket b: elems) {
System.out.println(b.filling.getVolume());
}
}
Will print:
5.0
12.0
Shame on me I wrote the whole code, but it's easier to understand by reading this one than reading a bad explanation I could write.
I have these two classes
public class Iris_Setosa {
private double sepal_length;
private double sepal_width;
private double petal_length;
private double petal_width;
//Constractor
public Iris_Setosa(double s_length,double s_width,double p_length,double p_width)
{
this.sepal_length=s_length;
this.sepal_width=s_width;
this.petal_length=p_length;
this.petal_width=p_width;
}
public double sepal_length()
{
return this.sepal_length;
}
public double sepal_width()
{
return this.sepal_width;
}
public double petal_length()
{
return this.petal_length;
}
public double petal_width()
{
return this.petal_width;
}
}
public class Iris_Versicolour {
private double sepal_length;
private double sepal_width;
private double petal_length;
private double petal_width;
//Constractor
public Iris_Versicolour(double s_length,double s_width,double p_length,double p_width)
{
this.sepal_length=s_length;
this.sepal_width=s_width;
this.petal_length=p_length;
this.petal_width=p_width;
}
public double sepal_length()
{
return this.sepal_length;
}
public double sepal_width()
{
return this.sepal_width;
}
public double petal_length()
{
return this.petal_length;
}
public double petal_width()
{
return this.petal_width;
}
}
I defined two vectors and set data:
Vector <Iris_Setosa> I_Setosa = new Vector <Iris_Setosa>();
Vector <Iris_Versicolour> I_Versicolour = new Vector <Iris_Versicolouלr>();
//data
I_Setosa.add(new Iris_Setosa (4.6,3.4,1.4,0.3));
I_Setosa.add(new Iris_Setosa (5.4,3.9,1.7,0.4));
I_Versicolour.add(new Iris_Versicolour(6.4,3.2,4.5,1.5));
I_Versicolour.add(new Iris_Versicolour(6.9,3.1,4.9,1.5));
.......
How do we classify these two vectors together, in order to be treated as points in space?
So now you have a new sample, s = [4.7, 3.3, 1.5, 0.5]
A first quick and dirty method would be 1NN (K Nearest Neighbors with K=1). In this case you would compute the euclidean distance between s and each of your four points.
You would find that four your four cases you have the distances 5.93, 6.40, 6.94, and 7.12. In this case you choose the first training sample since it is closest, leading to a prediction of I_Setosa. More specifically, it was most similar to Iris_Setosa (4.6,3.4,1.4,0.3)
Hope this helps