статический метод возвращает значение всем переменным

#java #arraylist

#java #arraylist

Вопрос:

В настоящее время я сталкиваюсь со следующей проблемой в моем Java-коде.Я пытался вызвать метод trHead(), который получает в качестве параметра arraylist и удаляет последние 3 элемента списка, а затем возвращает его.Проблема в том, что когда я запускаю свой код и вызываю метод trHead () для arraylist A, кажется, что он работает просто отлично, но на самом деле он изменяет не только arraylist A, но и arraylist B, даже не вызывая его для arraylist B.

Мой код следующий :

 import java.util.ArrayList;

public class S1Calculation {

private static final int δ = 30;
private static final double ε = 0.9;
private int LCSScount = 0;  

    //Calculate the LCSS for any two trajectories
    public int LCSS(ArrayList<Double> A, ArrayList<Double> B , ArrayList<Integer> tA , ArrayList<Integer> tB) {


        if((A.size()==0) || (B.size()==0)) {
            return LCSScount;
        }

        if((Math.abs(A.get(A.size()-1)-B.get(B.size()-1))<ε) amp;amp; (Math.abs(A.get(A.size()-2)-B.get(B.size()-2))<ε) amp;amp; (Math.abs(A.get(A.size()-3)-B.get(B.size()-3))<ε) amp;amp; (Math.abs(tA.get(tA.size()-1)-tB.get(tB.size()-1))<=δ)){
            ArrayList<Double> tmpA = new ArrayList<Double>();
            ArrayList<Double> tmpB = new ArrayList<Double>();
            ArrayList<Integer> tmptA = new ArrayList<Integer>();
            ArrayList<Integer> tmptB = new ArrayList<Integer>();
            System.out.println(A.size());
            System.out.println(B.size());
            tmpA = trHead(A);
            System.out.println(A.size());
            System.out.println(B.size());
            tmpB = trHead(B);
            System.out.println(A.size());
            System.out.println(B.size());
            tmptA = tmHead(tA);
            tmptB = tmHead(tB);
            System.out.println("yes");
            return (1 LCSS(tmpA,tmpB,tmptA,tmptB));
        }
    }

    public static ArrayList<Double> trHead(ArrayList<Double> Array) {
        System.out.println("im in");
        Array.remove(Array.size() -1);
        Array.remove(Array.size() -1);
        Array.remove(Array.size() -1);
        return Array;
    }

    public static ArrayList<Integer> tmHead(ArrayList<Integer> Times){
        Times.remove(Times.size()-1);
        return Times;
    }
}
  

Также моим основным является следующее :

 public class Main {

public static void main(String[] args){
    //Parse some csv files and insert them in a 2 dimensional arraylist
    File dir = new File("\Path\");
    List<ArrayList<Double>> Trajectories = new ArrayList<ArrayList<Double>>();
    List<ArrayList<Integer>> Timestamps = new ArrayList<ArrayList<Integer>>();
    for (File file : dir.listFiles()) {
        Trajectory tr1 = new Trajectory(file);
        Trajectories.add(tr1.getTrajectory());
        Timestamps.add(tr1.getTimestamp());
    }
    //Call LCSS method for 4 arraylists (csv files)
    int FinalLCSS = new S1Calculation().LCSS(Trajectories.get(0),Trajectories.get(0),Timestamps.get(0),Timestamps.get(0));
  

Обратите внимание, что я вызываю LCSS для одного и того же csv-файла, что означает, что списки массивов A и B, которые передаются методу LCSS, содержат одинаковые значения.То же самое касается tA и tB.

Когда я запускаю это, я получаю следующие результаты : введите описание изображения здесь
введите описание изображения здесь

Как вы можете видеть, метод trHead вызывается для списка массивов A, но это также влияет на размер списка массивов B.Любой hep был бы оценен!

Комментарии:

1. Вы вызываете его с одинаковой ссылкой на объект для обоих A и B . Итак, когда вы его изменяете, объект изменяется, поэтому все ссылки на него отображаются одинаково. Если вы не хотите, чтобы оно менялось, вам следует сделать копию.

2. В вашем main вызове int FinalLCSS = new S1Calculation().LCSS(Trajectories.get(0),Trajectories.get(0) ... . В вашем методе используется одна и та же ссылка для A и B . Это означает, что при изменении A вы автоматически изменяете B . Вам нужно создать копию для элемента, возвращаемого Trajectories.get(0)

Ответ №1:

Java передает объекты по ссылке.

При вызове LCSS(Trajectories.get(0),Trajectories.get(0),...) аргументы ArrayList<Double> A и ArrayList<Double> B в конечном итоге ссылаются (указывают на) на один и тот же объект, объект, расположенный в Trajectories позиции 0 .

Если вы хотите работать с отдельными объектами, вам нужно сделать копию.

 ArrayList<Double> tmpA = new ArrayList<>(A);
ArrayList<Double> tmpB = new ArrayList<>(B);
  

Теперь tmpA и tmpB будут содержать копии A и B и будут отличаться, даже если A и B одно и то же.