简体   繁体   中英

Is there a way I can reuse part of my code that does the same thing but access different attributes of a class in Java?

So I was doing a program there's supposed to verify if when cut, a triangle can produce two new triangles, I did all the logic and the code works just as it is supposed to, however as I was doing I noticed that I had to apply the same logic for different attributes over and over again, which seemed highly unproductive. Here's the code:

public static class Triangle{
        private int[] x = new int[3];
        private int[] y = new int[3];
    
        public int getX(int position) {
            return x[position];
        }
        public int getY(int position) {
            return y[position];
        }
        
        //Get the information regarding the points that make the triangle
        public void setDomains(Scanner readVar){     
            readVar.nextLine();
            this.x[0] = readVar.nextInt();
            this.y[0] = readVar.nextInt();
            this.x[1] = readVar.nextInt();
            this.y[1] = readVar.nextInt();
            this.x[2] = readVar.nextInt();
            this.y[2] = readVar.nextInt();
            
        }

        //Verify if one of the other points is lower or higher than the present one
        public boolean areDiffX(int i, int j, boolean isLower){
 
            if(isLower){
                if(this.getX(i) < this.getX(j)){
                    return true;
                };
            }else{
                if(this.getX(i) > this.getX(j)){
                    return true;
                };
            }
     
            return false;
        }
        //Verify if one of the other points is lower or higher than the present one
        public boolean areDiffY(int i, int j, boolean isLower){
     
            if(isLower){
                if(this.getY(i) < this.getY(j)){
                    return true;
                };
            }else{
                if(this.getY(i) > this.getY(j)){
                    return true;
                };
            }
     
            return false;
        }
    
        //Verify if from the X axes two new triangles can ensurge
        public boolean compareTriangleDomain(int i, int j, int k){
    
            boolean hasDomain = false;
            boolean hasCodomain = false;
    
            hasDomain = areDiffX(i, j, true);
            hasCodomain = areDiffX(i, k, false);
            if(hasDomain == true && hasCodomain == true){
                return true;
            }
     
            hasDomain = areDiffX(i, j, false);
            hasCodomain = areDiffX(i, k, true);
            if(hasDomain == true && hasCodomain == true){
                return true;
            }
    
            return false;
        }
        
        //Verify if from the Y axes two new triangles can ensurge
        public boolean compareTriangleCodomain(int i, int j, int k){
    
            boolean hasDomain = false;
            boolean hasCodomain = false;
    
            hasDomain = areDiffY(i, j, true);
            hasCodomain = areDiffY(i, k, false);
            if(hasDomain == true && hasCodomain == true){
                return true;
            }
     
            hasDomain = areDiffY(i, j, false);
            hasCodomain = areDiffY(i, k, true);
            if(hasDomain == true && hasCodomain == true){
                return true;
            }
     
            return false;
        }
        
        //Verify if from a certain point of a triangle can be produced two new triangles
        public boolean cutTriangle(int i, int j, int k){
     
           boolean halveTriangleX = compareTriangleDomain(i, j, k);
           boolean halveTriangleY = compareTriangleCodomain(i, j, k);
           if(halveTriangleX || halveTriangleY){
                return true;
           }
           return false;
     
        }

        //Verify if a triangle can produce two new triangles
        public void checkCut(){

            boolean canCut = false;
            boolean hasntCut = true;

            canCut = cutTriangle(0, 1, 2);
            if(canCut == true && hasntCut == true){
                System.out.println("YES");
                hasntCut = false;
            }
            canCut = cutTriangle(1, 0, 2);
            if(canCut == true && hasntCut == true){
                System.out.println("YES");
                hasntCut = false;
            }
            canCut = cutTriangle(2, 1, 0);
            if(canCut == true && hasntCut == true){
                System.out.println("YES");
            }
            else if(hasntCut == true){
                System.out.println("NO");
            }
           
        }
    }

I thought that maybe I could add a new parameter to the get function so to specify which axes I'm working with, but I don't know if this a dumb way to do it, any recommendations and advices are welcome I'm still a baby in java and coding in general.

There are a few ways to do this. I would go with simply writing a function which takes the values instead of the indices, and then two new functions which get the values:

public boolean areDiff(int a, int b, boolean isLower){
  if (isLower) {
    if (a < b) {
      return true;
    }
  } else {
    if (a > b) {
      return true;
    }
  }     
  return false;
}

and then:

public boolean areDiffX(int i, int j, boolean isLower){
   return areDiff(this.getX(i), this.getX(j), isLower);
}

and a similar areDiffY function.

You can rewrite compareTriangleDomain to take values and use areDiff and dispense with compareTriangleCodomain and areDiffX/Y .

Perhaps I dug too deep, but I want to suggest the following approach.

The triangle obviously consists of three points on the plane. Why not make a class to represent the point? I will use the record syntax that appeared in Java 14. I also add two methods for comparing points and two comparators. One allows you to compare points by x coordinate, the second by y .

import java.util.Comparator;
import java.util.function.ToIntFunction;

public record Point2D(int x, int y) {

    private static Comparator<Point2D> compareBy(ToIntFunction<Point2D> keyExtractor) {
        return (o1, o2) -> Comparator.comparingInt(keyExtractor).compare(o1, o2);
    }

    public static Comparator<Point2D> byX = compareBy(Point2D::x);
    public static Comparator<Point2D> byY = compareBy(Point2D::y);

    public boolean less(Point2D other, Comparator<Point2D> comp) {
        return comp.compare(this, other) < 0;
    }

    public boolean higher(Point2D other, Comparator<Point2D> comp) {
        return comp.compare(this, other) > 0;
    }
}

Now we can greatly simplify the Triangle class. The triangle is represented by an array of three points instead of six integers.

private final Point2D[] vertices = new Point2D[3];

public void setDomains(Scanner readVar) {
    readVar.nextLine();
    this.vertices[0] = new Point2D(readVar.nextInt(), readVar.nextInt());
    this.vertices[1] = new Point2D(readVar.nextInt(), readVar.nextInt());
    this.vertices[2] = new Point2D(readVar.nextInt(), readVar.nextInt());
}

And all other methods look like this

public boolean compareTriangle(int i, int j, int k, Comparator<Point2D> comp) {  
    boolean hasDomain;                                                             
    boolean hasCodomain;                                                           
                                                                                   
    hasDomain = vertices[i].less(vertices[j], comp);                               
    hasCodomain = vertices[i].higher(vertices[k], comp);                           
    if (hasDomain && hasCodomain) {                                                
        return true;                                                               
    }                                                                              
                                                                                   
    hasDomain = vertices[i].higher(vertices[j], comp);                             
    hasCodomain = vertices[i].less(vertices[k], comp);                             
    return hasDomain && hasCodomain;                                               
}                                                                                  
                                                                                   
public boolean cutTriangle(int i, int j, int k) {                                  
    boolean halveTriangleX = compareTriangle(i, j, k, Point2D.byX);              
    boolean halveTriangleY = compareTriangle(i, j, k, Point2D.byY);              
    return halveTriangleX || halveTriangleY;                                       
}                                                                                  

I have not tested this code (in my opinion it is identical to yours), so you should definitely check it out.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM