Упорядочьте структуры MATLAB (структуры) на Java

Структуры (или structs) являются массивами MATLAB® с элементами, к которым получают доступ текстовые полевые указатели.

Структуры состоят из контейнеров данных, названных fields. Каждое поле хранит массив некоторого типа данных MATLAB. Каждое поле имеет уникальное имя.

Поле в структуре может иметь значение, совместимое с любым типом данных MATLAB, включая массив ячеек или другую структуру.

В MATLAB структура создается можно следующим образом:

S.name = 'Ed Plum';
S.score = 83;
S.grade = 'B+' 
Этот код создает скалярную структуру (S) с тремя полями:
S = 
    name: 'Ed Plum'
    score: 83
    grade: 'B+'
Массив многомерной структуры может быть создан путем вставки дополнительных элементов:
S(2).name = 'Toni Miller';
S(2).score = 91;
S(2).grade = 'A-';
В этом случае массив структур размерностей (1,2) создается. Структуры с дополнительными размерностями также поддержаны.

Поскольку Java® исходно не поддерживает структуры MATLAB, упорядочивая структуры между сервером, и клиент включает дополнительное кодирование.

Маршалинг Struct между клиентом и сервером

Структурам MATLAB упорядочивают списки пар "имя-значение". Вы представляете их на Java с использованием класса поля, состоящие из тех же чувствительных к регистру имен.

Класс Java должен также иметь public get и методы set, заданные для каждого поля. Зависят ли потребности класса и get и методы set от того, используется ли он в качестве ввода или вывода или обоих.

Следующее является простым примером того, как структура MATLAB может быть упорядочена между клиентом и сервером Java.

В этом примере функция MATLAB sortstudents берет в массиве структур (см. Маршала Структуры MATLAB (Структуры) на Java для деталей).

Каждый элемент в массиве структур представляет различную информацию о студенте. sortstudents сортирует входной массив в порядке возрастания по счету каждого студента, можно следующим образом:

function sorted = sortstudents(unsorted)
% Receive a vector of students as input
% Get scores of all the students
scores = {unsorted.score};
% Convert the cell array containing scores into a numeric array or doubles
scores = cell2mat(scores);
% Sort the scores array
[s i] = sort(scores);
% Sort the students array based on the sorted scores array
sorted = unsorted(i);

Примечание

Даже при том, что этот пример только использует поле scores входной структуры, можно также работать с полями name и grade подобным образом.

Вы группируете sortstudents в развертываемый архив (scoresorter.ctf) с помощью приложения Production Server Compiler (см., Создают Развертываемый Архив для MATLAB Production Server для деталей), и сделайте его доступным на сервере в http://localhost:9910/scoresorter для доступа клиентом Java (см. Долю Развертываемый Архив).

Прежде, чем задать интерфейс Java, требуемый клиентом, задайте структуру MATLAB, Student, с помощью класса Java.

Student объявляет поля name, score и grade с соответствующими типами. Это также содержит public get и функции set, чтобы получить доступ к этим полям.

 Студент класса Java

Затем, задайте интерфейс Java StudentSorter, который вызывает метод sortstudents и использует класс Student, чтобы упорядочить вводы и выводы.

Поскольку вы работаете с типом struct, Student должен быть включен в аннотацию MWStructureList.

interface StudentSorter {
    @MWStructureList({Student.class})
    Student[] sortstudents(Student[] students) 
            throws IOException, MATLABException;
}

Наконец, вы пишете приложение Java (MPSClientExample) для клиента:

  1. Создайте MWHttpClient, и сопоставленный прокси (использование createProxy) как показано в Создают Клиент Java.

  2. Создайте неотсортированный студенческий массив структур на Java, который подражает struct MATLAB в именовании, количестве вводов и выводов, и введите валидность в MATLAB. Смотрите, что Клиент Java Кодирует Лучшые практики для получения дополнительной информации.

  3. Сортировка студенческого массива и отображения это.

import java.net.URL;
import java.io.IOException;
import com.mathworks.mps.client.MWClient;
import com.mathworks.mps.client.MWHttpClient;
import com.mathworks.mps.client.MATLABException;
import com.mathworks.mps.client.annotations.MWStructureList;

interface StudentSorter {
    @MWStructureList({Student.class})
    Student[] sortstudents(Student[] students) 
            throws IOException, MATLABException;
}

public class ClientExample {

    public static void main(String[] args){
    
        MWClient client = new MWHttpClient();
        try{
            StudentSorter s = 
               client.createProxy(new URL("http://localhost:9910/scoresorter"), 
                                                          StudentSorter.class );
            Student[] students = new Student[]{new Student("Toni Miller", 90, "A"), 
                                               new Student("Ed Plum",     80, "B+"),
                                               new Student("Mark Jones",  85, "A-")};
            Student[] sorted = s.sortstudents(students);
            System.out.println("Student list sorted in the 
                            ascending order of scores : ");
            for(Student st:sorted){
                System.out.println(st);
            }
        }catch(IOException ex){
            System.out.println(ex);
        }catch(MATLABException ex){
            System.out.println(ex);
        }finally{
            client.close();        
        }
    }
}

Сопоставьте имена полей Java с именами полей MATLAB

Классы Java, которые представляют структуры MATLAB, используют Бобы Java, класс Introspector (https://docs.oracle.com/javase/6/docs/api/java/beans/Introspector.html), чтобы сопоставить свойства с полями и его соглашениями о присвоении имен по умолчанию используется.

Это означает, что по умолчанию его метод decapitalize() используется. Это сопоставляет первую букву от поля Java в строчную букву. По умолчанию не возможно задать поле Java, которое сопоставит с полем MATLAB, которое запускается с верхнего регистра.

Можно заменить это поведение путем реализации класса BeanInfo с пользовательским методом getPropertyDescriptors(). Например:

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.beans.SimpleBeanInfo;
public class StudentBeanInfo extends SimpleBeanInfo
{
  @Override
  public PropertyDescriptor[] getPropertyDescriptors()
  {
  PropertyDescriptor[] props = new  PropertyDescriptor[3];
  try
  {
    // name uses default naming conventions so we do not need to
    // explicitly specify the accessor names.
    props[0] = new PropertyDescriptor("name",MyStruct.class);
    // score uses default naming conventions so we do not need to
    // explicitly specify the accessor names.
    props[1] = new PropertyDescriptor("score",MyStruct.class);
    // Grade uses a custom naming convention so we do need to
    // explicitly specify the accessor names.
    props[1] = new PropertyDescriptor("Grade",MyStruct.class,
                                      "getGrade","setGrade");
    return props;
  }
  catch (IntrospectionException e)
  {
    e.printStackTrace();
  }
  
  return null;
  }
}

Определение структур MATLAB, только используемых в качестве входных параметров

При определении структур Java как входных параметров следуйте этим инструкциям:

  • Гарантируйте, что поля в классе Java совпадают с именами полей в struct MATLAB точно. Имена полей являются чувствительными к регистру.

  • Используйте методы public get на полях в классе Java. Зависят ли потребности класса и get и методы set для полей от того, используется ли он в качестве ввода или вывода или обоих. В этом примере обратите внимание, что, когда student передается как вход методу sortstudents, только методы get для его полей используются, по условию упорядочивая алгоритм.

В результате, если класс Java задан для структуры MATLAB, которая используется только в качестве входного значения, методы set не требуются. Эта версия класса Student только представляет входные значения:

public class Student{

    private String name;
    private int score;
    private String grade;
    
    public Student(String name, int score, String grade){
        this.name = name;
        this.score = score;
        this.grade = grade;
    }

    public String getName(){
        return name;    
    }
    
    public int getScore(){
        return score;    
    }
    
    public String getGrade(){
        return grade;    
    }  
}

Определение структур MATLAB, только используемых в качестве Вывода

При определении структур Java как выходных параметров следуйте этим инструкциям:

  • Гарантируйте, что поля в классе Java совпадают с именами полей в struct MATLAB точно. Имена полей являются чувствительными к регистру.

  • Создайте новый экземпляр класса Java с помощью структуры, полученной от MATLAB. Сделайте так при помощи методов set или аннотации @ConstructorProperties, предоставленной Java. методы get не требуются для класса Java при определении структур MATLAB только для вывода.

Класс Student только для вывода с помощью методов set следует:

public class Student{

    private String name;
    private int score;
    private String grade;    
    
    public void setName(String name){
        this.name = name;
    }
    
    public void setScore(int score){
        this.score = score;
    }    
    
    public void setGrade(String grade){
        this.grade = grade;
    }
}

Класс Student только для вывода с помощью @ConstructorProperties следует:

public class Student{

    private String name;
    private int score;
    private String grade;    
    
    @ConstructorProperties({"name","score","grade"})
    public Student(String n, int s, String g){
        this.name = n;
        this.score = s;
        this.grade = g;
    }    
}

Примечание

Если и методы set и аннотация @ConstructorProperties предоставлены, методы set более приоритетны по сравнению с аннотацией @ConstructorProperties.

Определение структур MATLAB, используемых в качестве обоих вводов и выводов

Если класс Student используется в качестве обоих ввод и вывод, необходимо предоставить методы get, чтобы выполнить маршалинг к MATLAB. Для маршалинга из MATLAB используйте методы set или аннотацию @ConstructorProperties.