a class to programm matryoshka dolls - java

I want to implement matryoshka dolls.
If you open one doll, there will be a smaller one inside until a massive doll that does not contain any another doll.
My try:
public static class Puppe{
int massive;
Puppe contains;
public static boolean massiveOrNot(Puppe doll) {
if(doll.massive==0) return true;
else return false;
}
public static Puppe exchangeDoll(Puppe doll) {
Puppe newDoll=new Puppe();
doll=newDoll;
return doll;
}
}
I´m completly new to classes.
How can I save dolls within other dolls and for example count how many dolls are inside of one doll?
Best regards
sop

First thing get rid of static for now, you will need more of this objects.
Then you have to think about is your object going to contain.
public class Puppe{
Puppe container;
public boolean isContaining() {
if(container != null) return true;
return false;
}
public void setDoll(Puppe smallerOne) {
container = smallerOne;
}
public Puppe getDoll() {
if(container != null)
return container;
return nullptr;
}
}

Related

check EmptyOrNull for unknown amount of collections and maps

I am trying to achieve an util as this in Spring Boot:
public static boolean isAllEmptyOrNull(Collection... collectionList) {
for (Collection collection : collectionList) {
if (!Collections.isEmpty(collection)) {
return false;
}
}
return true;
}
so I can handle cases as:
isAllEmptyOrNull(listOfCat);
isAllEmptyOrNull(listOfDog, mapOfStringToString);
isAllEmptyOrNull(listOfDog, listOfCat);
isAllEmptyOrNull(listOfDog, listOfCat, mapOfStringToList, mapOfStringToMap);
Any help will be sincerely appreciated :)
Updated 2018-12-06
Thanks for the help of #Deadpool, my solution turns out:
public static boolean isAllCollectionEmptyOrNull(Collection... collections) {
for (Collection collection : collections) {
if (!Collections.isEmpty(collection)) {
return false;
}
}
return true;
}
public static boolean isAllMapEmptyOrNull(Map... maps) {
for (Map map : maps) {
if (!Collections.isEmpty(map)) {
return false;
}
}
return true;
}
Of course, you can use stream and method overloading as nullpointer does.
No. You cannot create it as generic as you are looking for since a Map is not a Collection.
And of course Collection... collectionList signifies var args for Collection type.
The only way would be to break them into two separate stubs as :
public static boolean isAllEmptyOrNull(Collection... collectionList) {
return Arrays.stream(collectionList).allMatch(Collection::isEmpty);
}
public static boolean isAllEmptyOrNull(Map... maps) {
return Arrays.stream(maps).allMatch(Map::isEmpty);
}
You can have two different util methods one for to check Collection objects and another one for Map objects, since Map is not child of Collection interface
public static boolean isAllEmptyOrNull(Collection... collectionList) {
return Arrays.stream(collectionList).anyMatch(item->item==null || item.isEmpty());
}
public static boolean isAllEmptyOrNull(Map... maps) {
return Arrays.stream(maps).anyMatch(item->item==null || item.isEmpty());
}
To check all objects null or empty
public static boolean isAllEmptyOrNull(Collection... collectionList) {
return Arrays.stream(collectionList).allMatch(item->item==null || item.isEmpty());
}
public static boolean isAllEmptyOrNull(Map... maps) {
return Arrays.stream(maps).allMatch(item->item==null || item.isEmpty());
}
You can try this:
public static boolean isAllEmptyOrNull(Collection... collectionList) {
return Arrays.stream(collectionList).anyMatch(Collection::isEmpty);
}

Is it possible to avoid duplicate code when implementing methods for two similar class?

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.

Changing an array using a method inside a class

I tried a lot to fix this class but it didn't work. I want to make a hotel(Array) and check and fill it with people defined in another class, but I need to add ,remove, check for empty items and return their indexes using methods inside the hotel class. the problem is when I change the array inside a method I couldn't return the changed value and when I tried adding other class members trying to work it out I ended with indexOutOfboundryException. Could you pleas take a look at the code and tell me if you see the mistakes why I couldn't return the changed value and why I get index out of boundry
Many thanks in advance!
package com.company;
public class Hotel1 {
private int numberOfRooms1; // Number of rooms
private Person[]bookingList1=new Person[numberOfRooms1];// booking list with initial length of the number of rooms
private int uniqueId1;
private Person person1;
private int currentIndex;
private boolean isEmpty=true;
public int getNumberOfRooms1() {
return numberOfRooms1;
}
private Ticket ticket1;
public Hotel1(int numberOfRoomss1) {// The constructor has one attribute which is the number of the rooms
this.numberOfRooms1 = numberOfRoomss1;
}
//check in method
public Boolean isEmpty(){
for (currentIndex=0;currentIndex<bookingList1.length;currentIndex++){
if (!bookingList1[currentIndex].equals(null))
isEmpty=false;
else isEmpty= true;
}
return isEmpty;
}
public int findEmptyRooms(){
if (isEmpty)
{
for (currentIndex=0;currentIndex<bookingList1.length;currentIndex++){
return currentIndex;
}
return currentIndex;
}
return currentIndex;
}
public Person checkIn1(Person person){
if (isEmpty==true){
return bookingList1[findEmptyRooms()]=person;
}
else {
System.out.println("There is no empty rooms");
return null;
}
}
}
Aarrghh so many bugs in few lines...
Sorry to be rude but please review the logic of your code, i don't all understand...
For example :
public int findEmptyRooms(){
if (isEmpty)
{
for (currentIndex=0;currentIndex
}
What this function is supposed to do ?!
for (currentIndex=0;currentIndex<bookingList1.length;currentIndex++){
return currentIndex;
}
Simply always retuns bookingList1.length + 1
(so that's why the call to checkIn1 throws an indexOutOfboundryException)
Another example :
public Boolean isEmpty(){
for (currentIndex=0;currentIndex<bookingList1.length;currentIndex++){
if (!bookingList1[currentIndex].equals(null))
isEmpty=false;
else isEmpty= true;
}
return isEmpty;
}
Is completely buggy, if you have an element in the array with null followed by non null elements, the isEmpty will returns false
I think you should reconsider all your code before posting the question to stack overflow
Thank you all for your answers that help me refactor the whole code and make it better and get it work just in case you want to see how it became just take a look`package com.company;
public class Hotel1 {
private int numberOfRooms1;// number of rooms
Person rooms[];
public Hotel1(int numberOfRooms1){ //the constructor
this.numberOfRooms1=numberOfRooms1;
Person[]rooms=new Person[numberOfRooms1];
this.rooms=rooms;
}
//Private method to check if the array has an empty place
private boolean isEmpty(){
boolean isEmpty =false;
for (int i=0;i<rooms.length;i++){
if (rooms[i]==null){
return true;
}
}
return isEmpty;
}
//Check in
public Person[] checkIn(Person person){
if (isEmpty()){
for (int i=0;i<rooms.length;i++){
if (rooms[i]==null){
rooms[i]=person;
return rooms;
}
else continue;
}
}
else {
System.out.println("There is rooms left for "+person.getFirstName()+" Sorry!");
}
return rooms;
}}

How can I return the right data type of a instance when this instance might have different data type?

I have this code in Modula-2,
PROCEDURE Prune(typeExp: TypeExp): TypeExp;
BEGIN
CASE typeExp.^class OF
| VarType:
IF typeExp^.instance = NIL THEN
RETURN typeExp;
ELSE
typeExp^.instance = Prune(typeExp^.instance);
RETURN typeExp^.instance;
END;
| OperType: RETURN typeExp;
END;
END Prune;
I have several problems when I try to convert this code into java. I can create an instance and judge if its instance is null and then choose what to return. But I don't really know what to do with the case 2, which is the instance might be a new Opentype(); because only one value can be returned in this case.
public TypeExp Prune(TypeExp typeExp){
TypeExp r = new VarType();
if (r.instance == null) {
return r;
}
else {
r.instance = Prune(r.instance);
return r.instance;
}
}
The second issue is I don't think I can call the function Prune() inside itself, so what can I do? Thanks in advance.
I dont really know Modula-2, but it might be something like this:
public TypeExp Prune(TypeExp typeExp) {
if (typeExp instanceof VarType) {
if (typeExp.instance == null) {
return typeExp;
}
else {
typeExp.instance = Prune(typeExp.instance);
return typeExp.instance;
}
} else if (typeExp instanceof OperType) {
return typeExp;
}
//if typeExp is not an instance of VarType or OperType
return null;
}
The Modula code does not return in all code paths. Thats not possible in Java. I inserted return null in those cases. Thats probably wrong for your application though.
Below example not same as your func, but I think you can modify to your needs. It hides your return types behind Type class => you can return objects of two classes.
Main
package com.type;
public class Main {
public static void main(String[] args) {
Type first = new FirstType();
Type second = new SecondType();
System.out.println(func(first).getTypeName());
System.out.println(func(first).getTypeName());
System.out.println(func(second).getTypeName());
}
public static Type func(Type type) {
if(type instanceof FirstType) {
type.setTypeName("First");
} else {
type.setTypeName("Second");
// something here
}
return type;
}
}
Type
package com.type;
public class Type {
private String typeName;
public Type() {}
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
}
FirstType
package com.type;
public class FirstType extends Type {
}
SecondType
package com.type;
public class SecondType extends Type {
}

How to build an array recursively

I want to build an array recursively I started this way and cant figure how to do it properly:
public class ConnectivityNode {
private Server server;
private ConnectivityNode parent;
private ArrayList<ConnectivityNode> children;
...
public Server[] getServerRoute(){
if(this.parent == null) { return null; }
return this.server + this.parent.getServerRoute(); //of course this isnt correct
}
}
The idea is to get an array of Servers
{ parent.parent.server1, parent.server2, server3 }
One option is to work with a List and create a helper function:
private void getServerRouter(List<Server> l) {
l.add(server);
if (parent != null) {
parent.getServerRouter(l)
}
}
public Server[] getServerRouter() {
List<Server> l = new ArrayList<>();
getServerRouter(l);
return l.toArray(new Server[l.size()]);
}
You might even consider returning the List from the public method (that might make more sense).
You will need an function with a parameter. So for example like this:
public void getServerRoute(Server actualServer){
children.add(actualServer);
if(actualServer.hasParent())
getServerRoute(actualServer.getParent());
}
As I do not know how you find the parent of a server I just assumed you have a function for that matter.
Use an ArrayList:
There are two ways to do this. If you have to return an array, you can use:
public Server[] getServerRoute()
{
if(this.parent == null)
{
return null;
}
ArrayList<Server> servers = new ArrayList<Server>();
servers.add(this.server);
servers.addAll(Arrays.asList(this.parent.getServerRoute()));
return servers.toArray(new Server[0]);
}
If it's okay to just return an ArrayList (which can trivially be converted into an array, just as we did above), it would be make the function simpler:
public ArrayList<Server> getServerRoute()
{
if(this.parent == null)
{
return null;
}
ArrayList<Server> servers = new ArrayList<Server>();
servers.add(this.server);
servers.addAll(this.parent.getServerRoute());
return servers;
}
if i understand you correcty, and you want to obtain route from current element to root element in your tree, it will be something like that:
public Server[] getServerRoute(){
List<Server> servers=new ArrayList<>();
walk(this,servers);
return servers.toArray(new Server[servers.size()]);
}
private static void walk(ConnectivityNode node,List<Server> servers)
{
servers.add(node.getServer());
if (node.getParent() != null)
{
walk(node.getParent(),servers);
}
}

Categories