ArrayList does not print removed objects - java

I have a class called Polynomial with an ArrayList made up of term objects, there is an external file that is read by a Scanner object in my test class. The Scanner reads the line for 4 different key words and acts accordingly. ex. INSERT 3 2. Would call my insert method and print out 3x^2. Now I have a delete method with two parameters. When I call the method in the test class nothing happens, the same thing gets printed and nothing has been removed. Am I missing something or doing it wrong all together? Any help is greatly appreciated.
public void delete (int coeff, int expo)
{
for (int i = 0; i<terms.size(); i++)
{
Term current = terms.get(i);
terms.remove(current.getCoeff());
terms.remove(current.getExpo());
}
}
I also have a Term class that creates a term object, and has two methods to get the coefficient and exponent.
Here is a snippet of my test class:
public static void main(String[] args) throws IOException
{
// TODO code application logic here
Polynomial polyList = new Polynomial();
Scanner inFile = new Scanner(new File("operations2.txt"));
while(inFile.hasNext())
{
Scanner inLine = new Scanner(inFile.nextLine());
String insert = inLine.next();
if(insert.equals("INSERT"))
{
int coeff = inLine.nextInt();
int expo = inLine.nextInt();
polyList.insert(coeff, expo);
}
if(insert.equals("DELETE"))
{
int coeff = inLine.nextInt();
int expo = inLine.nextInt();
polyList.delete(coeff, expo);
}
}
System.out.println(polyList.toString());
}
}
Edit: this is a sample of the .txt file that is being read by the scanner class:
INSERT 3 2
INSERT 4 4
INSERT 1 6
INSERT 2 0
INSERT 5 2
INSERT 6 3
PRODUCT
DELETE 3 2
INSERT 2 7
DELETE 4 4
INSERT 4 10
Edit: Here is the Term class:
class Term
{
//instance vars
private int coefficient;
private int exponent;
public Term(int coeff, int expo)
{
coefficient = coeff;
exponent = expo;
}
public int getCoeff()
{
return coefficient;
}
public int getExpo()
{
return exponent;
}
#Override
public int hashCode()
{
return coefficient + exponent;
}
#Override
public boolean equals(Object o)
{
if (!(o instanceof Term))
{
return false;
}
Term t = (Term)o;
return coefficient == t.coefficient && exponent == t.exponent;
}
}

If your delete() method is trying to delete the Twrm with the specified coefficients, I recommend the following:
Override the equals() method to return true if the argument is a Term with the same coefficient and exponential
Override the hashCode() method to return a hash based on the same two values
Since the equals() method should make a value comparison, such an implementation is quite reasonable.
Once you've done that, your delete method becomes one line:
terms.remove(new Term(coeff, expo));
The implementation should look like this:
// in the Term class
#Override
public boolean equals(Object o) {
if (!(o instanceof Term)
return false;
Term t = (Term)o;
return coeff == t.coeff && expo == t.expo;
}
Although overriding the hashCode method is not strictly required to make your code work, it is good practice, so here's an example impl:
#Override
public int hashCode() {
return 31 * coeff + expo;
}

You're not trying to remove the Term from the terms list, but rather trying to remove the coefficient and exponent.
for (int i = 0; i<terms.size(); i++)
{
Term current = terms.get(i); // Your list contains Term objects
terms.remove(current.getCoeff()); // but you are try to removing a coefficient
terms.remove(current.getExpo()); // and an exponent
}
Just a general note also that removing this way will not work because i will be getting larger and your list will be getting smaller. So by the time you get to remove the last term for example (where i = terms.size() - 1), there will only be 1 item left in the list. If you're trying to remove all of the items, consider the list's clear method.

Why does your delete method take the arguments coeff and expo ....
...it does not do anything with them.
In fact, the delete method looks very suspicious. You will need to give more detail on what the terms array looks like, right now it makes no sense.
rolfl

Related

Sort Array list of objects based on object attributes

I have list which contains a property class object, In the list i have 3 status
not_paid
paid
part_paid
I want to sort my list below mentioned order.
First - not_paid
second- part_paid
third -paid
How can I sort my list using Comparator class.?
public static Comparator<OrderHistoryItemData> COMPARE_BY_PAYMENT = new Comparator<OrderHistoryItemData>() {
public int compare(OrderHistoryItemData one, OrderHistoryItemData other) {
String p1 = one.getAttributes().getFieldPaymentStatus();
String p2 = other.getAttributes().getFieldPaymentStatus();
if (p1.equals(p2)) {
return 0;
}
if (p1.equals("not_paid") && (p2.equals("part_paid") || p2.equals("not_paid"))) {
return -1;
}
if (p1.equals("not_paid") && p2.equals("not_paid")) {
return -1;
}
return 1;
}
};
This is my Code. i am getting below order using this code.
paid-->not_paid-->part_paid
This is my Update Code. I got my result.
public static Comparator<OrderHistoryItemData> COMPARE_BY_PAYMENT = new Comparator<OrderHistoryItemData>() {
public int compare(OrderHistoryItemData one, OrderHistoryItemData other) {
String p1 = one.getAttributes().getFieldPaymentStatus();
String p2 = other.getAttributes().getFieldPaymentStatus();
if (p1.equals(p2)) {
return 0;
}
if (p1.equals("not_paid") && (p2.equals("part_paid") || p2.equals("paid"))) {
return -1;
}
if (p1.equals("part_paid") && p2.equals("paid")) {
return -1;
}
return 1;
}
};
To avoid complex comparator, I encourage you to export your statuses to an enum. (Plus this will work if you will add more statuses in the future, without the need to change logic in your comparator):
enum PaymentStatus { // Write them in order you want to be sorted
NOT_PAID,
PART_PAID,
PAID
}
Then sorting will be as simple as :
list.sort(Comparator.comparing(item ->item.getAttributes().getFieldPaymentStatus()));
What you can do is first mapping the strings to integers in the desired order, and then simply subtracting them from eachother.
private static Comparator<Payments> comparator = new Comparator<Payments>() {
// Use this mapping function to map the statuses to ints.
// The lowest number comes first
private int map(String str) {
switch (str) {
case "not_paid":
return 0;
case "part_paid":
return 1;
case "paid":
return 2;
default:
return 3;
}
}
// Alternatively, you can use the Map interface to define the sorting
// order.
#Override
public int compare(Payments o1, Payments o2) {
return map(o1.status) - map(o2.status);
}
};
I suggest – Schidu Luca already mentioned it in his answer – that you use enums to define a fixed set of known values, like payment statuses. This provides compile-time safety.
Note: I wouldn't, however, suggest to bind the enum declaration order to the sorting order.

Sorting an array and linking changes to another array of identical size

i am trying to sort an array of strings which are terms of a polynomial. every position is 1 term of the polynomial as a string, and signed approapriately, however i want to sort them in order by the power.
eg
+3x^5
+5
-8x
-4x^2
how i have approached this is by creating a second array storing just the power, and i want to sort them both based off this array. ie
for (int i=0; i<sortArray.length; i++) {
if (sortArray[i].indexOf("^")!= -1)
sortArrayDegree[i] = Integer.parseInt((sortArray[i].
substring(sortArray[i].indexOf("^") + 1, sortArray[i].length())));
else if (sortArray[i].indexOf("x")!= -1)
sortArrayDegree[i]=1;
else
sortArrayDegree[i]=0;
}
however i am not sure how to link the two, so any changes to the second happen to the first
currently that means the second array looks like this
5
0
1
2
i thought i could make a new array and store this as the second column(clash of data types), but that still leaves the sorting problem
I'm not sure that the way you want achieve this is the wisest way, but this is how you could do it:
Create a class of both the power and the number of the polynomial member. Make that class Comparable, then put it in one array and the sort method will use the comparable method you have overridden from the Comparable interface.
public class PolynomialMember implements Comparable<PolynomialMember> {
public int power; // public for brevity, but should be private with getters and setters
public String number; // public for brevity, but should be private with getters and setters
public PolynomialMember(String number, int power) {
this.number = number;
this.power = power;
}
#Override
public int compareTo(PolynomialMember o) {
return Integer.compare(this.power, o.power);
}
// optional: override for pretty printing
#Override
public String toString() {
if(!number.equals("0")) {
if(number.charAt(0) == '-') {
return number + "x^" + power;
} else {
return "+" + number + "x^" + power;
}
} else {
return "";
}
}
}
this way you don't need two arrays, and you certainly shouldn't "link" two arrays.
You can use this class like this:
public static void main(String[] args) {
List<PolynomialMember> polynom = new ArrayList<PolynomialMember>();
polynom.add(new PolynomialMember("-5", 3));
polynom.add(new PolynomialMember("7", 1));
polynom.add(new PolynomialMember("4", 0));
polynom.add(new PolynomialMember("8", 2));
for(PolynomialMember pm : polynom) {
System.out.print(pm + " ");
// prints: -5x^3 +7x^1 +4x^0 +8x^2
}
System.out.println();
Collections.sort(polynom); //this is where the magic happens.
for(PolynomialMember pm : polynom) {
System.out.print(pm + " ");
// prints: +4x^0 +7x^1 +8x^2 -5x^3
}
}
If I understand correctly, which I'm really not sure, you want to bind the data of 2 arrays containing value types\immutables. The easiest way i know to bind data from 2 arrays is to create a class containing both of them as private members and exposing public methods to control them. in these methods you could implement the logic that defines the relationship between them.

Check for multiple instances of same object in array

i am looking for a way to check if an array contains more than 1 instances of the same object. I've been looking around but can't seem to find anything in the javadoc nor stackoverflow.
I am creating a monopoly board game (or in danish, matador) where the fee from landing on one of the fields differs depending on how many of that type of field the player owns.
I have a list in my player class in which i put all the fields that the player buys:
public List<OwnableField> ownsList = new ArrayList<>();
public void buy(OwnableField ownable) {
pay(ownable.getPrice());
ownsList.add(ownable);
}
And then i have this method in the specific field class, in which i am working on an if statement to set the fee:
public int fee;
public int feeCalc(int diceScore) {
if(this.getOwner().ownsList.(whatever checks for duplicate object in array)){
fee = 200 * diceScore;
} else {
fee = 100 * diceScore;
}
return fee;
}
If you have a proper equals and hash code defined then you can use sets to achive that
List list = ...
if(new HashSet(list).size().equals(list.size()){
//same size
} else {
//there was a duplicated element
}
If you want to check for one specific object only you could do it with:
final Object someObject = ...
List list = ...
int size = FluentIterable.from(list).filter(new Predicate<Object>() {
#Override
public boolean apply(Object input) {
return input == someObject;
}
}).size();
if(size > 1) {
//there is a duplicated element
}
Or, if you are looking for an instance of a class, then try:
List list = ...
int size = FluentIterable.from(list).filter(Predicates.instanceOf(YourClass.class)).size();
if(size > 1) {
//there is a duplicated element
}

Am I returning the correct value from my method & am I writing it correctly?

I'll preface my question with the statement that I am very new to Java, so I apologise if my code is totally disgusting to read.
What I'm trying to do: I'm writing a program that takes two integers from the user, a low value and a high value, and sends both integers to two different methods. Method #1 has a simple for loop and should print out all of the numbers between the lowest number and the highest number that are multiples of 3 or 5, and Method #2 does the same except for numbers that are multiples of 3 or 5 it also checks if that number is also a multiple of 6 and, if so, it prints the number and an asterisk next to it.
What I'm having trouble with: I'm pretty stumped on what I need to return from my methods & how to return anything at all. This is the first time I've worked on a method properly (just moved up from "Hello World) and from what I can see I don't really need to return anything at all. All the code that I've put in my methods pretty much complete the program, so I thought maybe returning the integers I sent would be enough, apparently it's not. So, without further ado, here's my code.
The Error:
javac BonusQ.java
.\MethodOne.java:19: error: illegal start of type
return(int lowestRange, int highestRange);
^
.\MethodTwo.java:36: error: illegal start of type
return(int lowestRange, int highestRange);
^
The Main:
import java.util.Scanner;
public class BonusQ
{
public static void main(String [] args)
{
Scanner scan = new Scanner(System.in);
int lowestRange = 0;
int highestRange = 0;
System.out.println("Enter the lowest integer in your range");
lowestRange = scan.nextInt();
System.out.println("Enter the highest integer in your range");
highestRange = scan.nextInt();
MethodOne.NoAsterisk(lowestRange, highestRange);
MethodTwo.Asterisk(lowestRange, highestRange);
}
}
MethodOne:
public class MethodOne
{
public static int NoAsterisk(int lowestRange, int highestRange)
{
for(int i = lowestRange; i <= highestRange; i++)
{
if (i%5 == 0)
{
System.out.println(i);
}
else if (i%3 == 0)
{
System.out.println(i);
}
}
}
return(int lowestRange, int highestRange);
}
MethodTwo:
public class MethodTwo
{
public static int Asterisk(int lowestRange, int highestRange)
{
for(int i = lowestRange; i <= highestRange; i++)
{
if (i%5 == 0)
{
if (i%5 == 0 && i%6 == 0)
{
System.out.println(i + "*");
}
else
{
System.out.println(i);
}
}
else if (i%3 == 0)
{
if (i%3 == 0 && i%6 == 0)
{
System.out.println(i + "*");
}
else
{
System.out.println(i);
}
}
}
}
return(int lowestRange, int highestRange);
}
Sorry if the post is a bit beefy to read, I just find that adding my thoughts on the code might help you explain to me what's going wrong, seeing as you may not know the extent of my incompetence :)
Thanks in advance.
Ok, Classes have members.
Members are either some variables or arrays of variables
and the methods of a class.
So you got
public class MyMethod
{
public static int Asterisk(int loRange, int hiRange)
{
// Do magic let's make a sum for this example
// You enter loRange and hiRange (you defined it above)
return loRange + hiRange // Here the method returns a result
}
}
// So then....
public static void main(String [] args)
{
// WHATEVER IS IN HERE RUNS ALWAYS FIRST.
z = Asterisk(1,2); // 1 and 2 is lo and hi range values ;)
// Z has a value of 3 now because Asterisk(1,2) returns 1 + 2
}
See how this works?
Now this works because you use the static definition (meaning there must not be an instance of MyMethod created first to use the method. It's not wrong, but if you can make a program do things with class instances, you better do it that way.
You make an instance of a class, this is called an object, using a special method. This method has the exact name of the Class and constructs an instance of it.
You should study now about constructors, abstract classes etc etc.
I can't say you do it wrong or right either. It is about what the program is all about and you should study the scope for variables and methods, and the encapsulation concept of Object Oriented Programming.
Using only static methods, goes against encapsulation principle, it is possibly wrong but I can't tell for sure.
I hope this helped you and gave you a good direction to go on with your study.
PS:
To return multiple results, you should return an array of variables, not just a variable.
You can also return nothing and just have it do the job to a needed array. This FORCES you though to make this array public. (Not a good practice)
Finally if multiple value returns are needed to just print them on the console... well, just do it in the method, no need to return anything really.
You don't need to return anything, being that the methods are printing out all the values.
You can change them into void methods, for example:
public static void asterisk(int lowest, int highest) {
//loops and if statements
//no return statement!
}
The code in the methods will run and voila, you are done!
EDIT: That being said, there's a lot more than can be done to make this code more Java-like, but for now this will work.
mmmmm...you can return types, and (int lowestRange, int highestRange) its not a type. Look at the method definition
public static int Asterisk(int lowestRange, int highestRange)
the return type is declared as int, so you should return an int value. You can do something like
return lowestRange;
return 1;
with that in consideration, the error should dissapear. The question is, why do you need to return a value? From what i've read, your methods are supose to print stuff, not to return stuff...
The return statements are out of the method. You have to put them before the close method brackets.
public class MyClass{
public int sum (int a, int b){
return a + b;
} // The return have to be before this brackets
}

A customized object array sort in Java that does not sort

I've read a few tutorials on customizing Arrays.sort, and a lot of googling, but I'm missing the answer. Right now Arrays.sort(charList) does nothing. Here's what my code looks like.
public class character implements Comparable<character>{
//public vars
public String charName;
public int initModifier;
public int initRoll;
public int secondInit;
/* ... getters, setters, other vars .. */
#Override
public int compareTo(character another) {
int compareInit = ((character) another).getTotalInit();
int comp = this.totalInit - compareInit;
int compareSecondInit = ((character) another).getTotalInit();
if (comp != 0)
{
return comp;
}
else
{
return this.secondInit - compareSecondInit;
}
}
}
The main activity is a bundle of stuff. The part that deals with the arrays.sort follows:
//add a character to the array.
public void addResults(character c)
{
debugInt++; //using this to debug
if(debugInt==3)
{
Log.d(tag,charList[0].charName); //always prints the first object entered
Log.d(tag,charList[1].charName); //always prints the second object entered
}
if (playersPerTurn<charLimit)
{
charList[playersPerTurn]=c;
Arrays.sort(charList,0,playersPerTurn);
playersPerTurn++;
updateDisplay();
}
}
Help me SO, you're my only hope.
int compareSecondInit = ((character) another).getTotalInit();
You probably wanted getSecondInit() here.
Your compareTo() with this bug is not consistent - and thus the result is undefined.
for example:
element1:
totalInit = 1
secondInit = 2
element2:
totalInit = 1
secondInit = 2
element1.compareTo(element2) == 2 - 1 == 1
element2.compareTo(element1) == 2 - 1 == 1
As a side note, about coding practice:
Naming a class character is confusing, you should consider renaming it.
In java, the convention is that class names start with upper case letters. It will help fellow programmers to easily understand character is a class and not a field.

Categories