0Pricing
Java Academy · Урок

Двумерные утилиты как вспомогательный класс (рефакторинг)

Вынесите повторяющуюся логику работы с двумерными данными во вспомогательный класс, пригодный для повторного использования. Создайте статические утилиты для ширины столбцов, выровненного вывода, средних значений, максимумов и транспонирования. Используйте этот класс в небольших демонстрациях.

«Двумерные утилиты как вспомогательный класс (рефакторинг)» — бесплатный урок Java Academy на CoddyKit. Это урок 5 из 6. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 6 уроков всего.

Зачем выполнять рефакторинг

Зачем выполнять рефакторинг и создавать вспомогательный класс? Чтобы не копировать код, сохранить единственный источник истины и упростить последующие уроки. Мы создадим вспомогательный класс GradeUtil со статическими методами для вычисления ширины, выравнивания при печати, средних значений, максимумов и транспонирования.

Оболочка помощника и печать

Создайте статический GradeUtil с ширинами и printAligned. Затем из main вызовите GradeUtil.printAligned(m), чтобы вывести любую ступенчатую матрицу со столбцами, выровненными по ширине.

public class Main {
  // Static helper with reusable utilities for 2D int matrices
  static class GradeUtil {
    // Compute per-column widths (jagged-aware)
    static int[] widths(int[][] m) {
      int maxCols = 0;
      for (int r = 0; r < m.length; r = r + 1) if (m[r].length > maxCols) maxCols = m[r].length;
      int[] w = new int[maxCols];
      for (int r = 0; r < m.length; r = r + 1) {
        for (int c = 0; c < m[r].length; c = c + 1) {
          int len = Integer.toString(m[r][c]).length();
          if (len > w[c]) w[c] = len;
        }
      }
      for (int c = 0; c < w.length; c = c + 1) if (w[c] < 1) w[c] = 1;
      return w;
    }

    // Print matrix with aligned columns
    static void printAligned(int[][] m) {
      int[] w = widths(m);
      for (int r = 0; r < m.length; r = r + 1) {
        String line = "";
        for (int c = 0; c < m[r].length; c = c + 1) {
          String s = Integer.toString(m[r][c]);
          while (s.length() < w[c]) s = " " + s;
          line = line + s + (c + 1 < m[r].length ? " " : "");
        }
        System.out.println(line);
      }
    }
  }

  public static void main(String[] args) {
    // Demo: build a small jagged matrix and print it via the helper
    int[][] m = {
      {1, 23, 456},
      {7, 8},
      {90, 12, 3, 4}
    };
    System.out.println("Aligned print via GradeUtil:");
    GradeUtil.printAligned(m);
  }
}

Помощник для средних значений

Добавьте в помощник rowAverage и colAverage и вызовите их из main. При вычислении средних по столбцам необходимо учитывать длину каждой строки для безопасной работы со ступенчатыми массивами.

public class Main {
  static class GradeUtil {
    static double rowAverage(int[][] g, int r) {
      int sum = 0;
      for (int c = 0; c < g[r].length; c = c + 1) sum = sum + g[r][c];
      return (double) sum / g[r].length;
    }
    static double colAverage(int[][] g, int c) {
      int sum = 0;
      int count = 0;
      for (int r = 0; r < g.length; r = r + 1) {
        if (c < g[r].length) { sum = sum + g[r][c]; count = count + 1; }
      }
      return (double) sum / count;
    }
  }

  public static void main(String[] args) {
    int[][] g = {
      {78, 85, 90, 88, 92},
      {95, 91, 89, 93, 87},
      {60, 72, 70, 68, 75},
      {88, 84, 79, 85, 90}
    };

    // Use helper to compute row averages
    for (int r = 0; r < g.length; r = r + 1) {
      double avg = GradeUtil.rowAverage(g, r);
      System.out.println("student " + r + " avg = " + String.format("%.2f", avg));
    }

    // Use helper to compute column averages
    for (int c = 0; c < g[0].length; c = c + 1) {
      double avg = GradeUtil.colAverage(g, c);
      System.out.println("assignment " + c + " avg = " + String.format("%.2f", avg));
    }
  }
}

Помощники для транспонирования

Реализуйте транспонирование прямоугольных и ступенчатых матриц. Версия для ступенчатой матрицы создаёт строки для каждого индекса столбца и заполняет отсутствующие элементы нулями.

public class Main {
  static class GradeUtil {
    // Transpose rectangular matrix (R x C) -> (C x R)
    static int[][] transposeRect(int[][] m) {
      int rows = m.length;
      int cols = m[0].length;
      int[][] t = new int[cols][rows];
      for (int r = 0; r < rows; r = r + 1) {
        for (int c = 0; c < cols; c = c + 1) t[c][r] = m[r][c];
      }
      return t;
    }
    // Jagged-safe transpose (pads with 0)
    static int[][] transposeJagged(int[][] m) {
      int maxCols = 0;
      for (int r = 0; r < m.length; r = r + 1) if (m[r].length > maxCols) maxCols = m[r].length;
      int[][] t = new int[maxCols][];
      for (int c = 0; c < maxCols; c = c + 1) {
        t[c] = new int[m.length];
        for (int r = 0; r < m.length; r = r + 1) t[c][r] = (c < m[r].length) ? m[r][c] : 0;
      }
      return t;
    }
  }

  public static void main(String[] args) {
    int[][] rect = {
      {1, 2, 3},
      {4, 5, 6}
    };
    int[][] t = GradeUtil.transposeRect(rect);
    System.out.println("t[0][1] should be 2: " + t[0][1]);

    int[][] jag = {
      {9, 12, 7},
      {5},
      {8, 10}
    };
    int[][] tj = GradeUtil.transposeJagged(jag);
    System.out.println("tj[1][0] should be 12: " + tj[1][0]);
  }
}

Помощник для максимумов столбцов

Добавьте colMaxima для вычисления максимума в каждом столбце, безопасно обрабатывая ступенчатые строки. Используйте флаг наличия значения, чтобы избежать ложных минимумов, когда столбец пуст.

public class Main {
  static class GradeUtil {
    // Column maxima for a jagged matrix
    static int[] colMaxima(int[][] m) {
      int maxCols = 0;
      for (int r = 0; r < m.length; r = r + 1) if (m[r].length > maxCols) maxCols = m[r].length;
      int[] max = new int[maxCols];
      for (int c = 0; c < maxCols; c = c + 1) {
        int best = Integer.MIN_VALUE;
        boolean seen = false;
        for (int r = 0; r < m.length; r = r + 1) {
          if (c < m[r].length) {
            if (!seen || m[r][c] > best) { best = m[r][c]; seen = true; }
          }
        }
        max[c] = seen ? best : 0;
      }
      return max;
    }
  }

  public static void main(String[] args) {
    int[][] jag = {
      {9, 12, 7},
      {5},
      {8, 10}
    };
    int[] cm = GradeUtil.colMaxima(jag);
    System.out.print("col maxima: ");
    for (int i = 0; i < cm.length; i = i + 1) System.out.print(cm[i] + (i + 1 < cm.length ? " " : ""));
    System.out.println();
  }
}

Все утилиты вместе

Объедините утилиты в одном помощнике и запускайте их из единственного main: печать, вычисление средних, транспонирование и поиск максимумов столбцов. Это ваш повторно используемый набор инструментов для последующих уроков.

public class Main {
  static class GradeUtil {
    static int[] widths(int[][] m) {
      int maxCols = 0;
      for (int r = 0; r < m.length; r = r + 1) if (m[r].length > maxCols) maxCols = m[r].length;
      int[] w = new int[maxCols];
      for (int r = 0; r < m.length; r = r + 1) {
        for (int c = 0; c < m[r].length; c = c + 1) {
          int len = Integer.toString(m[r][c]).length();
          if (len > w[c]) w[c] = len;
        }
      }
      for (int c = 0; c < w.length; c = c + 1) if (w[c] < 1) w[c] = 1;
      return w;
    }
    static void printAligned(int[][] m) {
      int[] w = widths(m);
      for (int r = 0; r < m.length; r = r + 1) {
        String line = "";
        for (int c = 0; c < m[r].length; c = c + 1) {
          String s = Integer.toString(m[r][c]);
          while (s.length() < w[c]) s = " " + s;
          line = line + s + (c + 1 < m[r].length ? " " : "");
        }
        System.out.println(line);
      }
    }
    static double rowAverage(int[][] g, int r) {
      int sum = 0; for (int c = 0; c < g[r].length; c = c + 1) sum = sum + g[r][c];
      return (double) sum / g[r].length;
    }
    static double colAverage(int[][] g, int c) {
      int sum = 0; int count = 0;
      for (int r = 0; r < g.length; r = r + 1) { if (c < g[r].length) { sum = sum + g[r][c]; count = count + 1; } }
      return (double) sum / count;
    }
    static int[][] transposeRect(int[][] m) {
      int rows = m.length; int cols = m[0].length; int[][] t = new int[cols][rows];
      for (int r = 0; r < rows; r = r + 1) for (int c = 0; c < cols; c = c + 1) t[c][r] = m[r][c];
      return t;
    }
    static int[][] transposeJagged(int[][] m) {
      int maxCols = 0; for (int r = 0; r < m.length; r = r + 1) if (m[r].length > maxCols) maxCols = m[r].length;
      int[][] t = new int[maxCols][];
      for (int c = 0; c < maxCols; c = c + 1) { t[c] = new int[m.length]; for (int r = 0; r < m.length; r = r + 1) t[c][r] = (c < m[r].length) ? m[r][c] : 0; }
      return t;
    }
    static int[] colMaxima(int[][] m) {
      int maxCols = 0; for (int r = 0; r < m.length; r = r + 1) if (m[r].length > maxCols) maxCols = m[r].length;
      int[] max = new int[maxCols];
      for (int c = 0; c < maxCols; c = c + 1) {
        int best = Integer.MIN_VALUE; boolean seen = false;
        for (int r = 0; r < m.length; r = r + 1) if (c < m[r].length) { if (!seen || m[r][c] > best) { best = m[r][c]; seen = true; } }
        max[c] = seen ? best : 0;
      }
      return max;
    }
  }

  public static void main(String[] args) {
    int[][] g = {
      {78, 85, 90, 88, 92},
      {95, 91, 89, 93, 87},
      {60, 72, 70, 68, 75},
      {88, 84, 79, 85, 90}
    };

    System.out.println("Original gradebook:");
    GradeUtil.printAligned(g);

    System.out.println("Row averages:");
    for (int r = 0; r < g.length; r = r + 1) System.out.println(r + ": " + String.format("%.2f", GradeUtil.rowAverage(g, r)));

    System.out.println("Column averages:");
    for (int c = 0; c < g[0].length; c = c + 1) System.out.println(c + ": " + String.format("%.2f", GradeUtil.colAverage(g, c)));

    System.out.println("Transpose (rect):");
    GradeUtil.printAligned(GradeUtil.transposeRect(g));

    System.out.println("Column maxima:");
    int[] cm = GradeUtil.colMaxima(g);
    for (int i = 0; i < cm.length; i = i + 1) System.out.print(cm[i] + (i + 1 < cm.length ? " " : ""));
    System.out.println();
  }
}

Проверка вызова статического метода

Быстрая проверка: как вызвать статический помощник, который выводит матрицу?

Повторение и далее

Повторение: Вы вынесли распространённые операции над двумерными данными во вспомогательный класс GradeUtil и использовали его в нескольких демонстрациях. Благодаря этому код остаётся небольшим, понятным и единообразным во всех уроках.

Часто задаваемые вопросы

Урок «Двумерные утилиты как вспомогательный класс (рефакторинг)» бесплатный?

Да — полный текст урока «Двумерные утилиты как вспомогательный класс (рефакторинг)» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 6 уроков всего.

Чему я научусь в уроке «Двумерные утилиты как вспомогательный класс (рефакторинг)»?

Вынесите повторяющуюся логику работы с двумерными данными во вспомогательный класс, пригодный для повторного использования. Создайте статические утилиты для ширины столбцов, выровненного вывода, сред… Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Java Academy?

Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 5 из 6.

Сколько времени занимает урок «Двумерные утилиты как вспомогательный класс (рефакторинг)»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Java Academy?

Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Основы двумерных массивов и вложенный перебор
  2. Массивы разной длины и форматирование таблиц
  3. Максимумы строк и столбцов, транспонирование и форматирование
  4. Мини-проект: ведомость оценок
  5. Двумерные утилиты как вспомогательный класс (рефакторинг)
  6. Очистка и проверка двумерных данных
← Назад к Java Academy