I have to follow the below UML diagram to design a programme.
The programme is supposed to generate 2 random integers, and ask user for input the answer to the sum of said integers.
However, I am not sure how to make use of the method static void getTwoIntegers(MyInteger m, MyInteger n) , or what to put inside it.
I have tried initialising 2 MyInteger objects with MyInteger int_1 = new MyInteger(m); and (n) in this method, but get a "cannot be resolved" error everytime I call its getter method int_1.getInteger();
And since the method getTwoIntegers is void, I cannot just return 2 random integers. I'm truly stuck on how to utilise this method
Any ideas? Thanks so much
Simple demo of what your implementation can accomplish.
The MyInteger objects passed as parameters (m and n) can be modified by the implementation of getTwoIntegers using the setInteger method of the class.
public class Main
{
public static void main(String[] args) {
MyInteger a = new MyInteger(333);
MyInteger b = new MyInteger(444);
System.out.println("before: " + a.getInteger() + "," + b.getInteger());
getTwoIntegers(a,b);
System.out.println("after: " + a.getInteger() + "," + b.getInteger());
}
public static class MyInteger {
private int val;
public MyInteger() { val = 0; }
public MyInteger(int v) { val = v; }
public void setInteger(int n) { this.val = n; }
public int getInteger() { return val; }
}
static void getTwoIntegers(MyInteger m, MyInteger n) {
// in your case modify implementation to produce random numbers
m.setInteger(222);
n.setInteger(555);
}
}
Prints:
before: 333,444
after: 222,555
Gardener's answer nailed it. For the records, I'd like to share some more thoughts.
This class diagram is misleading. The parameters of an UML operation have a direction that should be indicated in front of the parameter name. It can be in, out, inout. If the direction is omitted in the diagram, UML assumes that it's an in argument. Which assumes that the parameter is not muted by the operation.
If it would have been correctly specified as getTwoIntegers(out m: MyInteger, out n: MyInteger) (yes, UML syntax order is slightly different from Java), you would have understood that the values of m and n are provided for the output of the values of the operation, and not as input. And indeed, as Gardener explained, in Java you can provide a class object that can then be mutated to store the results; because class objects are passed by reference (i.e. it's the same object that is used and not a copy). This is by the way why a class MyInteger is used in this lab instead of a built-in type int.
Other unrelated UML remarks: there is no static type modifier keyword in UML. Either is it marked as {static} or is it underlined. Last but not least, there should be no multiplicity on a dashed dependency arrow. Multiplicities are for associations, i.e. structural relationships.
Related
I recently started to learn about generics in Java, and I understand the basic concepts of generics. However, one thing I don't understand is that I don't know why the following method doesn't work:
public class Generics<T extends Number> {
T num;
Generics(T n){
num = n;
}
//...
T timesTwo() { //Return the value that's twice as much as 'num'
return num * 2;
}
}
It was my first approach, and I kind of understand why it is not working. The error message said: The operator * is undefined for the argument types(s) T, int.
I guess Java couldn't multiply the T and int type together. (But shouldn't the compiler be able to auto-unbox T since it's involved in an expression AND the class extends Number?)
So I gave up on this method and tried to replace it with this method:
T times(T i) { //This method was supposed to receive another T object as
//an argument and multiply them together, then return the output
return num * i;
}
But once again, the exact same error message appeared (the only change was that int was replaced by T).
Why is the code not working, and how can I fix it?
I agree with the first two comments. Also, it's not a generics problem, it's just that the method doesn't work because it's not supposed to work because the boxing assumption you concluded doesn't apply here.
Autoboxing and Unboxing are supplied for some of the Number types but not all. See table below: https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html
So while this works the way you expect (because both types are in the supported table):
public static void main(String[] args) {
Integer a = 3;
Integer b = 2;
Number answer = a * b;
System.out.println("Answer: " + answer);
}
This intuitively equivalent code will NOT work:
public static void main(String[] args) {
Number a = 3;
Number b = 2;
Number answer = a * b;
System.out.println("Answer: " + answer);
}
In fact, from the Compiler's perspective, it gives you the same cross-eyed look you would get if you tried this:
public static void main(String[] args) {
String a = "what does it even mean to multiply a string with a number..??";
Byte b = 2;
Number answer = a * b;
System.out.println("Answer: " + answer);
}
So to finish the point, from the compiler's perspective, since auto-boxing does not apply, it's just as confused as to how to multiply two Numbers as it is how to multiply two other random objects like a String and a Byte and reports the error accordingly
Preface
I'd like to saying two things:
I don't know how to phrase this question in a few words. So I can't find what I'm looking for when searching (on stackoverflow). Essentially, I apologize if this is a duplicate.
I've only been programming Java consistently for a month or so. So I apologize if I asked an obvious question.
Question
I would like to have a method with a parameter that holds (path to) an integer.
How is such a method implemented in Java code?
Restrictions
The parameter should be generic.
So, when there are multiple of that integer variables, the correct one can be used as argument to the method, when it is called (at runtime).
My Idea as Pseudo-Code
Here's the idea of what I want (in pseudo-code). The idea basically consist of 3 parts:
the method with parameter
the variables holding integer values
the calls of the method with concrete values
(A) Method
.
Following is the definition of my method named hey with generic parameter named pathToAnyInteger of type genericPathToInt:
class main {
method hey(genericPathToInt pathToAnyInteger) {
System.out.println(pathToAnyInteger);
}
}
(B) Multiple Integer Variables
Following are the multiple integer variables (e.g. A and B; each holding an integer):
class A {
myInt = 2;
}
class B {
myInt = 8;
}
(C) Method-calls at runtime
Following is my main-method that gets executed when the program runs. So at runtime the (1) previously defined method hey is called using (2) each of the variables that are holding the different integer values:
class declare {
main() {
hey("hey " + A.myInt);
hey("hey " + B.myInt);
}
}
Expected output
//output
hey 2
hey 8
Personal Remark
Again, sorry if this is a duplicate, and sorry if this is a stupid question. If you need further clarification, I'd be willing to help. Any help is appreciated. And hey, if you're going to be unkind (mostly insults, but implied tone too) in your answer, don't answer, even if you have the solution. Your help isn't wanted. Thanks! :)
Java (since Java 8) contains elements of functional programing which allows for something similiar to what you are looking for. Your hey method could look like this:
void hey(Supplier<Integer> integerSupplier) {
System.out.printl("Hey" + integerSupplier.get());
}
This method declares a parameter that can be "a method call that will return an Integer".
You can call this method and pass it a so called lambda expression, like this:
hey(() -> myObject.getInt());
Or, in some cases, you can use a so called method referrence like :
Hey(myObject::getInt)
In this case both would mean "call the hey method and when it needs an integer, call getInt to retrieve it". The lambda expression would also allow you to reference a field directly, but having fields exposed is considered a bad practise.
If i understood your question correctly, you need to use inheritance to achive what you are looking for.
let's start with creating a hierarchy:
class SuperInteger {
int val;
//additional attributes that you would need.
public SuperInteger(int val) {
this.val = val;
}
public void printValue() {
System.out.println("The Value is :"+this.value);
}
}
class SubIntA extends SuperInteger {
//this inherits "val" and you can add additional unique attributes/behavior to it
public SubIntA(int val) {
super(val);
}
#override
public void printValue() {
System.out.println("A Value is :"+this.value);
}
}
class SubIntB extends SuperInteger {
//this inherits "val" and you can add additional unique attributes/behavior to it
public SubIntB(int val) {
super(val);
}
#override
public void printValue() {
System.out.println("B Value is :"+this.value);
}
}
Now you method Signature can be accepting and parameter of type SuperInteger and while calling the method, you can be passing SubIntA/SuperInteger/SubIntB because Java Implicitly Upcasts for you.
so:
public void testMethod(SuperInteger abc) {
a.val = 3;
a.printValue();
}
can be called from main using:
public static void main(String args[]){
testMethod(new SubIntA(0));
testMethod(new SubIntB(1));
testMethod(new SuperInteger(2));
}
getting an Output like:
A Value is :3
B Value is :3
The Value is :3
Integers in Java are primitive types, which are passed by value. So you don't really pass the "path" to the integer, you pass the actual value. Objects, on the other hand, are passed by reference.
Your pseudo-code would work in Java with a few modifications. The code assumes all classes are in the same package, otherwise you would need to make everything public (or another access modifier depending on the use case).
// First letter of a class name should be uppercase
class MainClass {
// the method takes one parameter of type integer, who we will call inputInteger
// (method-scoped only)
static void hey(int inputInteger) {
System.out.println("hey " + inputInteger);
}
}
class A {
// instance variable
int myInt = 2;
}
class B {
// instance variable
int myInt = 8;
}
class Declare {
public static void main() {
// Instantiate instances of A and B classes
A aObject = new A();
B bObject = new B();
// call the static method
MainClass.hey(aObject.myInt);
MainClass.hey(bObject.myInt);
}
}
//output
hey 2
hey 8
This code first defines the class MainClass, which contains your method hey. I made the method static in order to be able to just call it as MainClass.hey(). If it was not static, you would need to instantiate a MainClass object in the Declare class and then call the method on that object. For example:
...
MainClass mainClassObject = new MainClass();
mainClassObject.hey(aObject.myInt);
...
I would like to pass a reference to a primitive type to a method, which may change it.
Consider the following sample:
public class Main {
Integer x = new Integer(42);
Integer y = new Integer(42);
public static void main(String[] args) {
Main main = new Main();
System.out.println("x Before increment: " + main.x);
// based on some logic, call increment either on x or y
increment(main.x);
System.out.println("x after increment: " + main.x);
}
private static void increment(Integer int_ref) {
++int_ref;
}
}
The output running the sample is:
x Before increment: 42
x after increment: 42
Which means int_ref was past to the function by value, and not by reference, despite my optimistic name.
Obviously there are ways to work around this particular example, but my real application is way more complex, and in general one would imagine that a "pointer" or reference to integer would be useful in many scenarios.
I've tried to pass Object to the function (then casting to int), and various other methods, with no luck. One workaround that seems to be working would be to define my own version of Integer class:
private static class IntegerWrapper {
private int value;
IntegerWrapper(int value) { this.value = value; }
void plusplus() { ++value; }
int getValue() { return value; }
}
Doing this, and passing a reference to IntegerWrapper does work as expected, but to my taste it seems very lame. Coming from C#, where boxed variable just remain boxed, I hope I just miss something.
EDIT:
I would argue my question isn't a duplicate of Is Java "pass-by-reference" or "pass-by-value"?, as my question isn't theoretical, as I simply seek a solution. Philosophically, all method calls in all languages are pass-by-value: They either pass the actual value, or a reference to the value - by value.
So, I would rephrase my question: What is the common paradigm to workaround the issue that in java I'm unable to pass a reference to an Integer. Is the IntegerWrapper suggested above a known paradigm? Does a similar class (maybe MutableInt) already exist in the library? Maybe an array of length 1 a common practice and has some performance advantage? Am I the only person annoyed by the fact he can store a reference to any kind of object, but the basic types?
Integer is immutable, as you may notice.
Your approach with private static class IntegerWrapper is correct one. Using array with size 1 is also correct, but in practice I have never seen using array for this case. So do use IntegerWrapper.
Exactly the same implementation you can find in Apache org.apache.commons.lang3.mutable.MutableInt.
In your example you also can provide Main instance to the static method:
public class Main {
private int x = 42;
public static void main(String[] args) {
Main main = new Main();
incrementX(main);
}
private static void incrementX(Main main) {
main.x++;
}
}
And finally, from Java8 you could define an inc function and use it to increment value:
public class Main {
private static final IntFunction<Integer> INC = val -> val + 1;
private int x = 42;
public static void main(String[] args) {
Main main = new Main();
main.x = INC.apply(main.x);
}
}
I wrote a sort function and class in Java:
public class MiscellaneousUtilities {
/**
* Changes a list of "First Last" to "Last, First" and "First Middle Last" to "Last, First Middle", etc.
*/
public static Function<String, String> ToLastFirstFunction = new Function<String, String>() {
#Override
public String apply(String nm) {
String[] nmarr = nm.split(" ");
int last = nmarr.length - 1;
String res = nmarr[last];
if (last > 0) {
res += ",";
}
for (int i = 0; i < last; i++) {
res += " " + nmarr[i];
}
return res;
};
};
}
When I want to use it I can't just say MiscellaneousFunctions.ToFirstLastFunction()
I have to do a new MiscellaneousFunctions().ToFirstLastFunction;
I tried putting static in front of the class declaration but it allows only public, final and abstract. Looking at the Math class if I want to use Math.min() I don't have to do a new Math().min(). Math is also defined as a class that does not have static in front of it, and min() does as does ToFirstLastFunction, so I don't understand the difference.
That's because you have to call that function with an apply like this:
MiscellaneousFunctions.ToFirstLastFunction.apply("yourstring");
You can add an other static function as a shorthand though:
public static String toFirstLast(String str) {
return ToLastFirstFunction.apply(str);
}
The main difference between Math.min and your solution that Math.min is a regular static method while you have a Function object and those can be called with apply.
Math.min() is a a method not a function, declared like this in Math.class:
public int min(int a, int b) {
...
}
... and it is methods like this that you can invoke directly as in int x = Math.min(3,2).
You have created a public static class variable called ToLastFirstFunction -- that's not something you can call like a method. But you can do things with it using the methods in the java.util.function.Function interface -- the simplest being apply():
String out = MiscellaneousFunctions.toFirstLastFunction.apply("John Doe");
(I changed the capitalisation of your identifier -- find out about Java capitalisation conventions)
It is not the case that you can call your public static Function<...> using new MiscellaneousFunctions().toFirstLastFunction("John Doe") -- I'm not sure why you thought it was so.
You can do new MiscellanousFunctions().toFirstLastFunction.apply("John Doe") -- but your compiler should warn you about accessing a static variable via an instance. MiscellanousFunctions.toFirstLastFunction.apply() is the right way.
So the short answer to your question is: if you want to invoke it that way, write it as a method.
But if that's the case, why would you define an operation as a function, rather than a method?
Well, functions have the benefit that, unlike methods(*), they are objects -- so you can pass them around, put them in collections, assign them to variables. And they have methods like compose() and andThen() which return a new function that combines this function with another.
So you can do things like:
Map<String,Function<String,String> nameTranslationStrategies = new HashMap<>();
nameTranslationStrategies.put(
"no change", x -> x);
nameTranslationStrategies.put(
"to first-last",
MiscellaneousFunctions.toFirstLastFunction);
nameTranslationStrategies.put(
"capitalised first-last",
MiscellaneousFunctions.toFirstLastFunction
.andThen( s -> s.toUpperCase());
...
String nameTranslationOption = config.getProperty("nameTranslationOption");
String name = nameTranslationStrategies
.get(nameTranslationOption)
.apply(inputString);
Java programmers managed for decades without this feature -- functions didn't exist until Java 8. But you can do lots of neat things with them.
Even so, this isn't a reason to write your code as a Function bound to a static variable, since you can access ordinary methods as functions using the :: syntax:
Function<Double,Double> logarithm = Math::log;
double x = logarithm.apply(2.0);
Note also, that you've used a long-winded syntax to define your function:
public static Function<String, String> slimify = new Function<String, String>() {
#Override
public String apply(String s) {
return "slim says " + s;
}
}
... can be written as:
public static Function<String,String> slimify = s -> {
return "slim says " + s;
}
... or even (since this one's a one-liner)
public static Function<String,String> slimify = s -> "slim says " + s;
It's good to know the long-winded way, because it shows how functions work behind the scenes. But in real world code, the shorter form is the way to go, as it is more expressive: the intent of the code isn't hidden by clutter. This is such a quick and easy way of expressing a function, that people often use them in-line rather than assign them to a variable -- as I have done in the map example above.
(*) I said that methods are not objects. This isn't strictly true -- partly because you can get one as an object using ::, but also because you can use Java's Reflection API to access classes and methods as objects. But you don't want to use Reflection, unless you really know you need to.
Math.min() is a public static method called min, your Function is a Function object, it's not a method. Your object has a method apply and you have to use that method for what you want to achieve, like this:
MiscellaneousFunctions.ToFirstLastFunction.apply(something)
Lets say this is the C++ code:
void change(int& x){
x++;
}
or
void change2(int* a){
*a++;
}
Both will change the global x, right?
So how can I do something like that in java?
Specifically, I want to point to a Vector object
But since Java has no pointers, I'm not sure what to do.
From searching the internet I saw people saying that Java does that in some other way, but I haven't found any real example.
Thanks for
help!
In Java, instead of pointers you have references to objects. You cannot pass a primitive type by reference, but you can wrap a primitive type inside an object and then pass a reference to that object.
Java provides the type Integer which wraps int, however this type is immutable so you cannot change its value after construction. You could however use MutableInt from Apache Commons:
void change(MutableInt x) {
x.increment();
}
The change to x will be visible to the caller.
Specifically, I want to point to a Vector object
When you write Vector v = ...; you are assigning a reference to a vector to the variable v. A reference in Java is very similar to a pointer. References are in fact implemented internally using pointers.
Java uses pass by value. When you pass a vector to a method, you are actually copying a reference to that vector. It does not clone the vector itself. So passing a reference in Java is very similar to passing a pointer in C++.
With Java you cannot pass primitive types like int by reference, they are passed only by value.
The only things you can do is to find artifices to do that, because instead Objects are passed by reference. Here two examples.
Use an array of single value, like this
int[] value = new int[1];
value[0] = 2;
// call a method
obj.setValue(value);
// and in setValue
public void setValue(int[] value) {
value[0] = 5;
}
Or second approach use an holder class:
public class Holder<T> {
public T value;
public Holder(T value) {
this.value = value;
}
}
// then use it in this way
Holder<Integer> h = new Holder<Integer>(2);
obj.setValue(h);
// and in setValue
public void setValue(Holder<Integer> h) {
h.value = 5;
}
In this case I use an holder class implements with generics but you can have a simple holder too, only for integer. For example:
public class IntHolder {
public int value;
public IntHolder(int value) {
this.value = value;
}
}
Java always passes by value and there are no global variables as in the C++ sense. So if you want to do the same as in C++ you need to return the new value.
Thusly:
public int change(int x) {
return ++x;
// or
// return x + 1;
}
To test it:
int x = 2;
change(x);
System.out.println(x); // returns 2
x = change(x);
System.out.println(x); // returns 3
So it doesn't make any sense to let the method be called change, it is more sensible along the lines of calculateThisInt.
Java does pass objects by value. But as Mark Byers mentions the Integer class is immutable and you could use MutableInt from Apache Commons library. To describe how this works you could implement it yourself for your example:
public class MyInt() {
public int i;
public void setInt(int i) {
this.i = i;
}
public int getInt() {
return this.i;
}
public int increment() {
this.i++;
}
}
You need to change your change function to have the above MyInt object as argument:
public void change(MyInt i) {
i.increment();
}
Usage:
MyInt x = new MyInt();
x.setInt(2);
change(x);
System.out.println(x.getInt); // returns 3
In your case you want to change a Vector object...
public void changeVector(Vector v) {
// anything you do with 'v' will change it even
// for the scope that called this method
}
// Usage:
Vector v = new Vector();
changeVector(v);
// v should be changed after calling change vector method
Hope this all makes sense.
Both will change the global x, right?
So how can I do something like that in java? Specifically, I want to
point to a Vector object
The question is somewhat vague, but I got the impression that you ultimately want a global Vector that you can keep stuff in?
Many ways to do that, but one of the simplest is to have a static field in a class, with public static methods for accessing it. (Or simply a public static field which is accessed directly, but that really wouldn't be idiomatic in Java.)
public class Foo {
private static List<Integer> globalVector = new Vector<Integer>();
public static void add(int number){
globalVector.add(number);
}
// ... plus whatever other accessors to the global list that you need
}
Anywhere else in code:
Foo.add(23); // modifies the global vector
(Btw, Vector is kinda obsolete, and typically we'd use ArrayList in its place now. As the Javadoc says, it's been retrofitted to implement the List interface, which I also used in the example.)
While you can't replace an object that's been passed to a function, you can change its state by altering fields directly or calling methods. If you need something like a pointer to a primitive, wrap it in an object. To follow your code, you could do this:
public class IntPointer {
public int value;
public IntPointer(int value) {
this.value = value;
}
}
Then elsewhere you could say:
public static void change(IntPointer ipoint) {
ipoint.value++;
}
public static void main(String[] args) {
IntPointer a = new IntPointer(10);
change(a);
}
This might seem a bit awkward, but it hasn't come up for me as often as you'd think. I'd be more likely to do something like this:
public class ABPair {
private int a = 0;
private int b = 0;
public static void changeA() {
a++;
}
public static void changeB() {
b++;
}
}
So that elsewhere I can say:
public static void main(String[] args) {
ABPair ab = new ABPair();
if (ACondition) {
ab.changeA();
}
}
In other words, my data tends to already be wrapped in some sort of object, and I tend to use the data object's methods to mediate any changes.
Java supports what it calls "references". References act alot like pointers in C/C++-like languages. They don't act the same way "references" work in those languages.
The major differences between a pointer in C and a reference in Java are:
You can't do pointer arithmetic in Java (i.e. you can't "add" or "subtract" from a Java reference, you can only dereference it or compare it with another one).
You can't cast it to an incompatible type: Java is strongly type-safe, you can't "re-interpret" the bytes in memory as some other object.
For some uses of pointers this has no real effect (for example linked lists work pretty much the same in both languages), for others the difference is quite major (arrays in C are just fancy pointer arithmetic, in Java they work quite differently).
So in a way Java references could be called "restricted pointers".