Is it possible to prevent an int from being subtracted from? The final keyword wouldn't work here, as I still need to be able to add to it. Thanks!
public class AddButNoSubtract {
private int i; // private
public int getI() {
return i;
}
public void incrementBy(int j) { // instead of setter
// add if positive
if (j > 0) {
// check for overflow
if (Integer.MAX_VALUE - j >= i)
this.i += j;
}
}
}
You may use Integer wrapper class instead of int as Integer class is immutable.
Another idea:
Do not expose your string as a public variable, simply provide method(s) to modify that int. And if someone tries to subtract that string then you can control that within your method.
even if you just disable the subtract then users can still add a negative number... and thus bypass your defense. a wrapper is the only thing you can use here
public class myInteger{
private int innerVal;
public int getInnerVal(){ return innerVal};
public void myInteger(int val) { innerVal = val;}
public void add(myInteger secondInt)
{
int sum = innerVal + secondInt.innerVal;
if(sum > innerVal)
{
innerVal = sum;
}
}
}
Is it possible to prevent an int from being subtracted from?
If the int variable is accessible (and not final) then No.
The only way to do this kind of thing is to make the variable inaccessible (e.g. private) and then provide methods that allow the caller what you want to happen, and forbid the things that you don't want to happen.
Related
public void run() {
moveTest();
}
private int moveTest() {
while (frontIsClear()) {
move();
for (int i = 0; i < 0; i++);
}
}
There is the code, I want to basically count the loop (in order to find the middle point of an straight line, and then store the count into an ' int ' and than use that int (value) in another private method (or public if it needs to).
Thanks in advance hope you guys can understand my point ^^
Your question is not clear and strange, but I thing you can just create a private field in a class, return the result of method moveTest in it, and then use it in another method...
Like:
private int count = 0;
public void run() {
count = moveTest();
// use 'count'variable
}
private void someMethodUsingCountVariable() {
int a = count;
}
Not to sure why the integers lowRange and highRange are not going between these classes.
package guessnumber;
public class GuessNumber
{
static public int computerGenedNumber;
static public int lowRange;
static public int highRange;
static public int playerGuess;
public static void main(String[] args)
{
Input.range(lowRange, highRange);
Rand.number(lowRange, highRange, computerGenedNumber);
Input.guess();
Give.result();
}
}
Next Class:
package guessnumber;
import javax.swing.JOptionPane;
class Input
{
public static void range(int lowRange, int highRange)
{
String rawUserInput;
rawUserInput = JOptionPane.showInputDialog("Please enter the range you wish to guess. (EX: 1-10)", "1-10");
for(int i = 0; i < rawUserInput.length(); i++)
{
if(rawUserInput.charAt(i) == '-')
{
lowRange = Integer.parseInt(rawUserInput.substring(0, i));
highRange = Integer.parseInt(rawUserInput.substring(i + 1, rawUserInput.length()));
}
}
}
static void guess()
{
}
}
And the last relevant one:
package guessnumber;
class Rand
{
static public void number(int lowRange, int highRange, int computerGenedNumber)
{
computerGenedNumber = (int)(Math.random() * (highRange - lowRange) + lowRange);
}
}
The rest of the classes are currently blank so I don't think I need to put them here too.
Here is a simplified piece of code which reproduce your problem, and make sure you understand why it is causing problem and the solution:
class Foo {
public static void square(int a, int result) {
result = a*a;
}
}
class Bar {
public static void main(String[] args) {
int a=2;
int result = 0;
Foo.square(a, result);
System.out.println("result " + result);
}
}
This should be fundamental understanding of Java. Checkout what is the meaning of "pass-by-value"
In brief, the parameter passed in the method is a copy of the argument. Therefore when you are changing the parameter in your method, you are just changing another piece of data, and your change is not reflected to caller.
One way to fix is to change the method and return your result, which looks like:
class Foo {
public static int square(int a) {
return a*a;
}
}
class Bar {
public static void main(String[] args) {
int a=2;
int result = 0;
result = Foo.square(a);
System.out.println("result " + result);
}
}
Another common solution is to pass in a "holder object" as the result. Although the object reference is passed by value, that copy of object reference is still pointing to the same object as caller. I won't go too deep into this as it is less common and you should be able to get the proper way doing so once you have better understanding on how value (including object reference) is passed around.
Parameters are passed "by value" in Java. What that means is that when you call
input.range(lowRange, highRange);
it gives the current values of those variables to input.range, but it doesn't give input.range a way to modify them. In the range method:
public static void range(int lowRange, int highRange)
the parameters lowRange and highRange (which have no connection with the variables in GuessNumber, even though the names are the same) are copies of what you pass in. When you assign lowRange = ... in the method, it changes the copy but has no effect at all on the lowRange and highRange in GuessNumber.
You need to write a range method that returns two values. This needs a little bit of work, but I'd write a Range class that has low and high members, and then change your method to
public static Range range()
That method would have to create a new Range object. I think it's OK for low and high to be public members of Range:
class Range {
public int low;
public int high;
public Range(int low, int high) {
this.low = low;
this.high = high;
}
}
Normally, public data in a class is a bad thing, but for a class whose only purpose is to let a method return multiple values, it's OK in my opinion.
Is there a short hand for defining the access modifiers of a classes fields and methods? More in a C++ style, I've searched but keep coming up with sites explaining what the purpose of each modifier is rather than a short hand.
public class myNum {
public int getNum() { return 0; }
public void setNum(int n) { int num = n; }
private int num;
private String value;
}
Could become
public class myNum {
public:
int getNum() { return 0; }
void setNum(int n) { int num = n; }
private:
int num;
String value;
}
For methods nope.
For variables you could try
public int n1,n2,n3..n;
private int n1,n2,n3..n;
But as you can see it can become messy quickly.
And even then, it doesn't allow for different types under one access modifier.
But really nope.
Although there is no short for defining methods, Eclipse can automatically generate getter and setter methods for you.
What I do not understand is why I am getting an error compiling my code when a String is in fact an object, and the compiler is saying otherwise. I dont know why I keep getting this error message
symbol: method compareTo(Object)
location: variable least of type Object
.\DataSet.java:17: error: cannot find symbol
else if(maximum.compareTo(x) < 0)
here is the code. I'm trying to utilize the class comparable to allow two objects to use the compareTo method. In the tester, I'm just trying to use a basic string object to compare.
public class DataSetTester
{
public static void main(String[] args)
{
DataSet ds = new DataSet();
String man = "dog";
String woman = "cat";
ds.add(man);
ds.add(woman);
System.out.println("Maximum Word: " + ds.getMaximum());
}
}
Class:
public class DataSet implements Comparable
{
private Object maximum;
private Object least;
private int count;
private int answer;
public void add(Object x)
{
if(count == 0){
least = x;
maximum = x;
}
else if(least.compareTo(x) > 0)
least = x;
else if(maximum.compareTo(x) < 0)
maximum = x;
count++;
}
public int compareTo(Object anObject)
{
return this.compareTo(anObject);
}
public Object getMaximum()
{
return maximum;
}
public Object getLeast()
{
return least;
}
}
Comparable Interface:
public interface Comparable
{
public int compareTo(Object anObject);
}
Of course String is an Object.
Comparable is generic now. Why do you feel the need to make those references Object if they are type String? Your code is poor; it's not a Java problem.
I don't see why DataSet needs to implement Comparable. You just need to compare incoming Strings as they're added. Do it this way and you'll fare better:
public class DataSet {
private String maximum;
private String least;
private int count;
private int answer;
public void add(String x) {
if(count == 0){
least = x;
maximum = x;
} else if (least.compareTo(x) > 0) {
least = x;
} else if(maximum.compareTo(x) < 0) {
maximum = x;
}
count++;
}
public String getMaximum() { return this.maximum; }
public String getLeast() { return this.least; }
public int getCount() { return this.count; }
}
The problem is that DataSet implements Comparable, but Object doesn't.
Instead of storing Objects, you want to store Comparables. However, if you do get this to compile, you will get into an infinite loop right here:
public int compareTo(Object anObject)
{
// Yeah, never stop loopin'!
return this.compareTo(anObject);
}
It's recommended that in newer code, you use the generic Comparable<T> interface. Your code would then look like this:
public class DataSet implements Comparable<DataSet>
{
private String maximum;
private String least;
private int count;
private int answer;
public void add(String x)
{
if(count == 0){
least = x;
maximum = x;
}
else if(least.compareTo(x) > 0)
least = x;
else if(maximum.compareTo(x) < 0)
maximum = x;
count++;
}
public int compareTo(DataSet anObject)
{
// I don't really know how you want this to work.
// Come up with your own criteria on what makes a DataSet greater or less than
// another one.
count - anObject.count
}
// Good practice to include this if you're doing a compareTo.
#Override
public boolean equals(Object other)
{
return (other instanceof DataSet) && compareTo((DataSet)other) == 0;
}
public String getMaximum()
{
return maximum;
}
public String getLeast()
{
return least;
}
}
Edit - just saw that you're comparing strings. In that case, you don't really need DataSet to implement Comparable. However, if you do need it for something else, what I wrote still stands.
least and maximum are simply Objects, and the Object class doesn't have a compareTo(...) method, simple as that. least and maximum need to be declared Comparable, not Object. And as written, it makes no sense declaring DataSet to implement the Comparable interface since there are no DataSet objects present and certainly none being compared.
java.lang.Object does not have a compareTo() method.
First of all there is an infinite loop in you code:
public int compareTo(Object anObject)
{
return this.compareTo(anObject);
}
this method is continuously calling itself.
Regarding your compile error: you have declared variable as Object, which obviously does not have a compareTo method.
There is no compareTo() method in Object. I guess you're looking for String.compareTo().
Type checking is done at compile time and not runtime. At compile time, least and maximum are considered to be objects of type Object and not String.
All the methods here are correct, but my problem is that i have to find a part in the parts array that has a certain weight. So After i do the getweight method I think i have to call that. But the last part of the code is what i have a problem with. It starts with the line public Part getPartWithWeight (int weight){
class Robot {
Part[] parts;
public Robot () {// assume these are right}
}
public void addPart(Part p) { // assume these are right}
}
class Part {
// Class details not shown
public double getWeight() {//... }
}
public int getPartnum() {//...}
}
public String getMaterial() {//...}
}
public Part getPartWithWeight (int weight){
for(int i = 0; i < parts.length; i ++){
if (parts[i].weight == weight) {
return parts[i];
}
}
Well, here's the "works-out-of-the-box" version.
Step 1 Write a comparator.
class PartComparator implements java.util.Comparator<Part> {
#Override
public int compare(Part part1, Part part2) {
return part1.weight - part2.weight;
}
public final static PartComparator instance = new PartComparator();
}
The comparator class should be static if you declare it inside Part (which is what I would suggest).
Step 2 Use the comparator
public Part getPartWithWeight (int weight){
Part pivot = new Part();
pivot.weight = weight;
int idx = Arrays.binarySearch(parts, pivot, PartComparator.instance);
return parts[idx];
}
if (parts[i].weight == weight)
should say
if (parts[i].getWeight() == weight)
You should use getWeight() because that's the method defined in the Parts class.
Also if you're problem is getting the parts array from the robot class and using it in the part class then you should just pass it as a parameter.
public Part getPartWithWeight (int weight, Part[] parts){
for(int i = 0; i < parts.length; i ++){
if (parts[i].getWeight() == weight) {
return parts[i];
}
}
}
Then when you call the method getPartWithWeight() make sure you put the array in there too.
EDIT: Also per Ray Cheng's comment, the weight you're looking for is supposed to be an int but your getWeight() method returns a double.... so either your getWeight() should return an in or you should typecast it as an int before making the comparison. Be aware that if you typecast it as an int you will lose some precision. It would be better to fix your getWeight() so it returns a double like you need it to.
To implement a binary search, you first need to cut the array in half and then decide which half you want to begin the search. Then you cut the halved array in half again and repeat...
Unless you want to implement your own, but looks like there is a built-in one you can call.
http://docs.oracle.com/javase/7/docs/api/index.html?java/util/Arrays.html