I am studying these codes below got from a website (source: https://gist.github.com/allisons/842546). Can anyone please explain the usage of the variable __processCalled? I don't get why it is put in the constructor and how it affects the process method (in both subclass and super class). It seems to me that this boolean variable is assigned values but is not actually used (like in the if statement: if (__processCalled) {}).
Thank you so much for your help!
//Provided Code
public class Account {
public boolean __processCalled;
public Account(Client c) {
__processCalled = false;
}
public boolean process(Transaction t) {
__processCalled = true;
return t.value() > -100 && t.value() < 1000000;
}
public class Client {}
public class Transaction {
private int value;
public Transaction(int v) {
value = v;
}
public int value() {
return value;
}
}
}
//My Code
public class FilteredAccount extends Account{
private boolean __processCalled;
private int filteredCount;
private int transactionCount;
public FilteredAccount(Client c) {
super(c);
__processCalled = false;
filteredCount = 0;
transactionCount = 0;
}
public boolean process(Transaction t){
transactionCount++;
__processCalled = true;
if(t.value == 0){
filteredCount++;
return true;
}else{
return super.process(t);
}
}
public double percentFiltered(){
if(transactionCount == 0){
return 0.0;
}
return filteredCount/transactionCount *100;
}
}
Related
I need to make a programm which is like a rally, theres 2 types of vehicles, motorcycle and cars, two types of motorcycle, with and without sidecar, the thing is that I need to verify if there is just a motorcycle in an array list, I mean, two wheels vehicle. That verification should be done in a method called esDe2Ruedas(), which is called by an abstract overrided method called check() that should be the one that verifies if a group of vehicles from an array are able to run in the rally, if its true all the elements of the array must be from the same type.
Here is the code
this is how the program arrays the vehicles
GrandPrix gp1 = new GrandPrix();
gp1.agregar(v1);
//gp1.mostrar(v1);
gp1.agregar(v2);
System.out.println(gp1.check());
GrandPrix gp2 = new GrandPrix();
gp2.agregar(vt1);
gp2.agregar(vt2);
gp2.agregar(m2);
System.out.println(gp2.check());
GrandPrix gp3 = new GrandPrix();
gp3.agregar(vt1);
gp3.agregar(vt2);
gp3.agregar(m1);
System.out.println(gp3.check());
GrandPrix gp4 = new GrandPrix();
gp4.agregar(m1);
gp4.agregar(m2);
System.out.println(gp4.check());
This is the class that is using
import java.util.ArrayList;
public class GrandPrix extends Rally{
ArrayList<Vehiculo> ve = new ArrayList<Vehiculo>();
public void agregar(Vehiculo v) {
ve.add(v);
}
public void agregar(Carro c) {
ve.add(c);
}
public void agregar(Moto m) {
ve.add(m);
}
#Override
boolean check() {// HERE I VERIFY IF THE VEHICLES ARE COMPATIBLE
return false;
}
}
This is the class where everything goes on
public class Vehiculo {
private String Nombre;
private double velocidad_max;
private int peso;
private int comb;
public Vehiculo() {
setNombre("Anónimo");
setVel(130);
setPeso(1000);
setComb(0);
}
public Vehiculo(String string, double d, int i, int j) {
setNombre(string);
setVel(d);
setPeso(i);
setComb(j);
}
double rendimiento() {
return velocidad_max/peso;
}
public boolean mejor(Vehiculo otroVehiculo) {
return rendimiento()>otroVehiculo.rendimiento();
}
public String toString() {
return getNombre()+"-> Velocidad máxima = "+getVel()+" km/h, Peso = "+getPeso()+" kg";
}
/**************************************
---------SET And GET Nombre------------
***************************************/
public String getNombre() {
return Nombre;
}
public void setNombre(String nuevoNombre) {
this.Nombre=nuevoNombre;
}
/**************************************
---------SET And GET velocidad_max------------
***************************************/
public double getVel() {
return velocidad_max;
}
public void setVel(double nuevaVel) {
this.velocidad_max=nuevaVel;
}
/**************************************
---------SET And GET peso------------
***************************************/
public double getPeso() {
return peso;
}
public void setPeso(int nuevoPeso) {
this.peso=nuevoPeso;
}
/**************************************
---------SET And GET comb------------
***************************************/
public int getComb() {
return comb;
}
public void setComb(int comb) {
this.comb = comb;
}
boolean esDe2Ruedas() {
return false;
}
}
This is the class of motorcycles, which is in theory the same as the car's class, without sidecar thing
public class Moto extends Vehiculo{
private boolean sidecar;
public Moto(String string, double d, int i, int j) {
setNombre(string);
setVel(d);
setPeso(i);
setComb(j);
setSidecar(false);
}
public Moto(String string, double d, int i, int j, boolean b) {
setNombre(string);
setVel(d);
setPeso(i);
setComb(j);
setSidecar(b);
esDe2Ruedas(false);
}
public String toString() {
String str = null;
if(isSidecar())
str =super.toString()+", Moto, con sidecar";
else
str =super.toString()+", Moto";
return str;
}
public boolean isSidecar() {
return sidecar;
}
public void setSidecar(boolean sidecar) {
this.sidecar = sidecar;
}
I guess what you presented is what is given. If you came up with the design it is ok, but I believe it could be improved. Anyway, I try to respond to what I believe was your question straight away.
Vehiculo is the super type of Moto (which can have a side car and becomes 3 wheeler).
Vehiculo has a method esDe2Ruedas, which returns false.
Moto inherits that method <-- this is wrong, it should override it and, depending on side car, return the expected boolean value.
In the check method you can now distinguish between Moto and "Moto with sidecar" by using that method.
I have two classes: Fish and Plant. They do not inherit from any classes.
But both of them have one method called isAlive() which have the same implementation details. Now I have a list of fish and another list of dog and I need to remove dead fish and dead dog. I want my method to have same name but it is not possible without adding additional field to method signature. Is it possible I do not need to write additional chunk of code which does the same as the last chunk of code?
Below is the code. For class Model, Fish and Plant are two data members and they are ArrayList of Fish and Plant objects.
Is there any way I can write only one method called count and I do not need to add additional field to my method signature or modify my return type?
public class Fish{
public boolean isAlive(){
if(this.size > 0){
return true;
}
return false;
}
}
public class Plant{
public boolean isAlive(){
if(this.size > 0){
return true;
}
return false;
}
}
public class Model{
private int countDeadFish() {
int totalCount = 0;
for(Fish aFish : this.fish) {
if(aFish.isAlive() == false) {
totalCount += 1;
}
}
return totalCount;
}
private int countDeadPlants() {
int totalCount = 0;
for(Plant plant : this.plants) {
if(plant.isAlive() == false) {
totalCount += 1;
}
}
return totalCount;
}
}
If you do not want to use inheritance, then you can use a common method:
public class AliveChecker {
public static boolean isAlive(int size) {
return size > 0;
}
}
public class Plant{
public boolean isAlive(){
return AliveChecker.isAlive(this.size);
}
}
public class Fish{
public boolean isAlive(){
return AliveChecker.isAlive(this.size);
}
}
Since Fishand Plant do not inherit from anything yet you can consider creating a superclass and extend from it:
public class LivingThing {
protected int size = 1;
public boolean isAlive() {
return size > 0;
}
}
public class Plant extends LivingThing {
}
public class Fish extends LivingThing {
}
This example uses inheritance to classify Plantand Fish into the superclass LivingThing. You can set the size for example in the constructor of the Plant or an instance method:
public class Plant extends LivingThing {
public Plant(int size){
this.size = size;
}
}
Your Model could then be:
public class Model{
private int countDeadFish() {
return countDead(this.fish);
}
private int countDeadPlants() {
return countDead(this.plants);
}
private int countDead(ArrayList<LivingThing> things) {
int totalCount = 0;
for(LivingThing thing: things) {
if(!thing.isAlive()) {
totalCount++;
}
}
return totalCount;
}
}
Use interface
public interface LiveObject {
boolean isAlive();
}
public class Fish implements LiveObject {
public boolean isAlive(){
if(this.size > 0){
return true;
}
return false;
}
}
public class Plant implements LiveObject {
public boolean isAlive(){
if(this.size > 0){
return true;
}
return false;
}
}
public class Model{
private int countDead(Collection<LiveObject> objects) {
int totalCount = 0;
for(LiveObject obj : objects) {
if(obj.isAlive() == false) {
totalCount += 1;
}
}
return totalCount;
}
private int countDeadFish() {
return countDead(this.fish);
}
}
Based on the comments it seems you can't modify Fish or Plant. Here's an approach to reduce duplication in countDead<Something> methods which does not require this.
Basically you want to count items in an array which satisfy certain criteria. With Java 8 you can capture this criteria in a predicate using lambdas or method references. You do not need inheritance or implementation of a certain interface for this.
private long countDeadFish() {
return countDeadItems(this.fish, Fish::isAlive);
}
private long countDeadPlants() {
return countDeadItems(this.plants, Plant::isAlive);
}
private <T> long countDeadItems(Collection<T> items, Predicate<? super T> isAlive) {
return items.stream().filter(isAlive.negate()).count();
}
You could create a utility method (in a utility class somewhere):
public final class Liveliness {
private Liveliness() {
}
public static boolean isAlive(final IntSupplier sizer) {
return sizer.getAsInt() > 0;
}
}
Your method then becomes:
public boolean isAlive(){
return Liveliness.isAlive(this::getSize);
}
Alternatively, use an interface Life:
public interface Life {
int getSize();
default boolean isAlive(){
return getSize() > 0;
}
}
This way, adding a getSize method and inheriting from Life will add the method.
Note, avoid the following antipattern:
if(test) {
return true;
} else {
return false;
}
Use return test.
public class Coin
{
/**
* Creates a new Coin object.
*/
public Coin()
{
private boolean headup;
public void flip ()
{
headup = Math.random() < 0.5;
}
public boolean isHeads()
{
return headup;
}
public String toString()
{
if (headup)
return "Heads";
else
return "Tails";
}
}
}
can someone tell me what did i do wrong for my code?
You've nested methods inside of a constructor, something not legal in Java.
Solution: get those methods out of the constructor and out on their own in the class.
public class Coin {
private boolean headup;
public Coin() {
}
public void flip() {
headup = Math.random() < 0.5;
}
public boolean isHeads() {
return headup;
}
public String toString() {
if (headup)
return "Heads";
else
return "Tails";
}
}
So I'm having this problem with adding an element to an ArrayList
I have a class Media with 3 fields and another class Mediatheque with 1 field(which is an ArrayList).
Let's say I have:
A Mediatheque media = new Mediatheque
An equals(Media m) method in class Media < (important method)
I need to write a method add(Media m) which:
If the media.contenu does contain an element equals to the Media m I want to add, I must NOT add it and increase the nbEx field of the element contained in media.contenu
-Else I can add it using the add method provided by the ArrayList ( This doesn't seem too hard)
So I tried to write a contains(Media) method which uses the equals(Media m) method I wrote for the Media class and then use the contains method in the add method.
My question is that how am I supposed to write the add method? < (The Question)
I must write this using ArrayList, it is a school assignment
Sorry about the long code and the bad English, I'm a complete noob.
Here is my Media class:
package Ex1;
public class Media {
private final String support; // Format: Book, CD, DVD,etc...
private final String titre; // Title
private int nbEx; // Number of copy
public Media(String titre, String support){
this.titre = titre;
this.support = support;
this.nbEx = 1;
}
public Media (){
titre = "";
support = "";
nbEx = 0;
}
public boolean equals(Media m){
boolean equality = false;
if (m instanceof Media){
equality = (this.titre.equals(m.titre) && this.support.equals(m.support));
}
return equality;
}
public Media(Media m){
this.titre = m.titre;
this.support = m.support;
}
}
And here is my Mediatheque class:
import java.util.ArrayList;
import static java.lang.System.out;
public class Mediatheque {
ArrayList<Media> contenu;
public Mediatheque(){
this.contenu = new ArrayList<Media>();
}
public Mediatheque(Mediatheque m){
this.contenu = m.contenu;
}
public boolean contains(Media m){
int i = 0;
boolean contain = this.contenu.get(i).equals(m);
for(i = 0; i<this.contenu.size(); i++){
if(contain)
break;
}
return contain;
}
public int indexOf(Media m){
boolean retVal = this.contenu.get(i).equals(m);
for(Media i : contenu){
if(contain)
break;
}
return i;
}
public void add(Media m){
if(this.contains(m)){
this.contenu.get(this.contenu.indexOf(m)).setNbEx(this.contenu.get(this.contenu.indexOf(m)).getNbEx()+m.getNbEx());
}else{
this.contenu.add(m);
}
}
My question is that how am I supposed to write the add method?
Sorry about the long code and the bad English, I'm a complete noob.
Thank you!
As stated by #NeplatnyUdaj in the comment of your question, the use of a Map would greatly improve your code. Instead of recording the number of medias inside the Media object, use a HashMap<Media, Integer> to store your data in this way:
new HashMap<Media, Integer> map = new HashMap<Media,Integer>();
if ( map.containsKey(key) ) {
map.put(key, (map.get(key) + 1));
} else {
map.put(key, 1);
}
Where key is the media. (m in your code)
When one overrides the equals() method, one is also supposed to override the hashCode() method. The equals() method takes an Object parameter. Here's how your Media class should look like:
// Media.java
public class Media
{
private final String support;
private final String title;
public Media(String title, String support)
{
this.title = title;
this.support = support;
}
public Media(Media media)
{
this(media.title, media.support);
}
#Override
public int hashCode()
{
return 31 * title.hashCode() + support.hashCode();
}
#Override
public boolean equals(Object object)
{
if (object instanceof Media)
{
Media media = (Media) object;
return media.title.equals(title) &&
media.support.equals(support);
}
return false;
}
}
Then use a HashMap to map the media with its number of copies. Here's how that's done:
// MediaMap.java
import java.util.HashMap;
import java.util.Map;
public class MediaMap
{
// Media to its Number of Copies mapping.
private Map<Media, Integer> mediaMap;
public MediaMap()
{
mediaMap = new HashMap<>();
}
public void add(Media media)
{
mediaMap.put(media, mediaMap.getOrDefault(media, 0) + 1);
}
public void removeOneMedia(Media media)
{
if (mediaMap.containsKey(media))
{
mediaMap.put(media, mediaMap.get(media) - 1);
}
}
// And so on...
}
Without overriding the hashCode() method in the Media class, the hash based collections won't work as expected.
You can also have a look at MultiSet data structure, and use that instead.
If you are to use ArrayList then here's how its done:
// Media.java
public class Media
{
private final String support;
private final String title;
private int numberOfCopies;
public Media(Media media)
{
this(media.title, media.support, media.numberOfCopies);
}
public Media(String title, String support, int numberOfCopies)
{
this.title = title;
this.support = support;
this.numberOfCopies = numberOfCopies;
}
#Override
public int hashCode()
{
return 31 * title.hashCode() + support.hashCode();
}
#Override
public boolean equals(Object object)
{
if (object instanceof Media)
{
Media media = (Media) object;
return media.title.equals(title) &&
media.support.equals(support);
}
return false;
}
public int getNumberOfCopies()
{
return numberOfCopies;
}
public void setNumberOfCopies(int numberOfCopies)
{
this.numberOfCopies = numberOfCopies;
}
}
And here's a MediaList class which uses ArrayList:
// MediaList.java
import java.util.ArrayList;
public class MediaList
{
private ArrayList<Media> mediaList;
public MediaList()
{
mediaList = new ArrayList<>();
}
public void add(Media media)
{
set(media, +1);
}
public void remove(Media media)
{
set(media, -1);
}
private void set(Media media, int change)
{
if (change == 0)
{
return;
}
int indexOfMedia = mediaList.indexOf(media);
if (indexOfMedia != -1)
{
Media m = mediaList.get(indexOfMedia);
m.setNumberOfCopies(m.getNumberOfCopies() + change);
if (change < 0 && m.getNumberOfCopies() <= 0)
{
mediaList.remove(media);
}
}
else if (change > 0)
{
mediaList.add(media);
}
}
// And so on...
}
I have refactored your classes a little bit. I also implemented an add method. I assumed that you want to add media to the mediatheque if it is not already in the list. If it is in the list you want to add the nbex to the nbex that the item in the list has, right?
As the others I would advise you to use a HashMap() for counting if you don't need the number for your media objects.
Media.class
public class Media {
private final String support; // Format: Book, CD, DVD,etc...
private final String titre; // Title
private int nbEx; // Number of copy
public Media(String titre, String support){
this.titre = titre;
this.support = support;
this.nbEx = 1;
}
public Media(Media m){
this(m.titre, m.support);
}
public Media (){
this("", "");
nbEx = 0;
}
public boolean equals(Media m){
if (m instanceof Media){
return (this.titre.equals(m.titre) && this.support.equals(m.support));
}
return false;
}
}
Mediatheque.class
public class Mediatheque {
ArrayList<Media> contenu;
public Mediatheque(){
this.contenu = new ArrayList<Media>();
}
public Mediatheque(Mediatheque m){
this.contenu = m.contenu;
}
public boolean contains(Media m){
for(Media media: this.contenu) {
if(media.equals(m) {
return true;
}
}
return false;
}
public int indexOf(Media m){
if(this.contenu.contains(m) {
return this.contenu.indexOf(m);
}
return -1;
}
public void add(Media m){
if(this.contains(m)) {
Media media = this.contenu.get(this.contenu.indexOf(m));
media.setNbex(media.getNbex() + m.getNbex());
} else {
this.contenu.add(m);
}
}
}
Hope this helps.
My binary tree looks pretty close to my class materials, but when I print to the console or check for contains(), any adds I'm doing aren't registered.
I don't have a great understanding of static and the debugger is giving me a hint about making a static reference to non-static variable overallRoot, but everything compiles without error or warning in eclipse.
public class BSTSimpleSet<E extends Comparable<E>> implements SimpleSet<E> {
private GTNode<E> overallRoot;
private int size;
public static void main(String[] args) {
BSTSimpleSet<Integer> main = new BSTSimpleSet<Integer>(2);
main.toString();
main.add(3);
main.toString();
main.add(4);
main.toString();
main.add(5);
main.toString();
System.out.print(main.contains(3));
}
public BSTSimpleSet() {
size = 0;
}
public BSTSimpleSet(E input) {
overallRoot = new GTNode<E>(input);
size = 1;
}
public boolean add(E e) {
return add(e, overallRoot);
}
private boolean add(E e, GTNode<E> root) {
if (root == null) {
root = new GTNode<E>(e);
size++;
return true;
} else {
int compare = e.compareTo(root.data);
if (compare == 0) {
return false;
} else if (compare < 0) {
return add(e, root.left);
} else {
return add(e, root.right);
}
}
}
public void clear() {
overallRoot = null;
}
public boolean contains(E e) {
return contains(e, overallRoot);
}
private boolean contains(E e, GTNode<E> root) {
if (root == null) {
return false;
} else {
int compare = e.compareTo(root.data);
if (compare == 0) {
return true;
} else if (compare < 0) {
return contains(e, root.left);
} else {
return contains(e, root.right);
}
}
}
public boolean isEmpty() {
if (overallRoot == null) {
return false;
} else {
return true;
}
}
public int size() {
return size;
}
public String toString() {
this.toString(overallRoot, 0);
return null;
}
private void toString(GTNode<E> root, int level) {
if (root != null) {
for (int i = 0; i < level; i++) {
System.out.print(" ");
}
System.out.println(root.data);
toString(root.left, level + 1);
toString(root.right, level + 1);
} else {
for (int i = 0; i < level; i++) {
System.out.print(" ");
}
System.out.println("_");
}
}
private static class GTNode<E extends Comparable<E>> {
public E data;
public GTNode<E> left;
public GTNode<E> right;
public GTNode(E input) {
this(input, null, null);
}
public GTNode(E input, GTNode<E> lNode, GTNode<E> rNode) {
data = input;
left = lNode;
right = rNode;
}
}
}
This code does absolutely nothing.
private boolean add(E e, GTNode<E> root) {
if (root == null) {
root = new GTNode<E>(e);
size++;
return true;
}
...
Java passes in the Object Reference to a method. If you change the Reference, that will not
be propagated back to the calling method. If you change what the Reference refers to
that will be propagated back.
eg
// arrays behave the same way so using them to illustrate.
public void callMethods(){
int[] array = new int[1];
array[0] = 0;
doesNotChange(array);
System.out.println(array[0]);// will print 0
doesAChange(array);
System.out.println(array[0]);// will print 1
}
public void doesNotChange(int[] myArray){
myArray = new int[1];
myArray[0] = 1;
}
public void doesAChange(int[] myArray){
myArray[0] = 1;
}
To avoid these sorts of things I recommend always setting method parameters final.
The GTNode class shouldn't be static. Static classes are classes with only static methods, which means they don't have to be instantiated. The prototypical example of this is the java.lang.Math class: You don't need to call something like Math m = new Math(); m.cos(); to get the cosine, you just call Math.cos(). Since you're creating multiple instances of the GTNode class, make it non-static and you should be good.