MATLAB's ДЛЯ цикл статичен по своей природе; Вы не можете изменить переменную цикла между повторениями, в отличие от этого, для (инициализация; условие; инкремент) циклическая структура на других языках. Это означает, что следующий код всегда печатает 1, 2, 3, 4, 5 независимо от значения B.
A = 1:5;
for i = A
A = B;
disp(i);
end
, Если Вы хотите быть в состоянии ответить на изменения в структуре данных во время повторений, , В ТО ВРЕМЯ КАК цикл может быть более соответствующим---, Вы будете в состоянии протестировать условие цикла при каждом повторении и установить значение переменной (переменных) цикла, как Вы желаете:
n = 10;
f = n;
while n > 1
n = n-1;
f = f*n;
end
disp(['n! = ' num2str(f)])
Btw, для - каждый цикл в Java (и возможно другие языки) производит неуказанное поведение, когда структура данных изменяется во время повторения. Если необходимо изменить структуру данных, необходимо использовать соответствующее Итератор экземпляр, который позволяет дополнение и удаление элементов в наборе, которого Вы выполняете итерации. Хорошие новости - то, что MATLAB поддерживает объекты Java, таким образом, можно сделать что-то вроде этого:
A = java.util.ArrayList();
A.add(1);
A.add(2);
A.add(3);
A.add(4);
A.add(5);
itr = A.listIterator();
while itr.hasNext()
k = itr.next();
disp(k);
% modify data structure while iterating
itr.remove();
itr.add(k);
end
Это можно сделать, сохранив ссылку на тип Class
. Однако, на мой взгляд, проверки равенства должны касаться значений, которые представляют объекты, а не конкретных типов, которые выражаются значениями .
Классическим примером этого является, например, API коллекций. new ArrayList
возвращает true
. Хотя они имеют совершенно разные типы, они представляют одно и то же значение, а именно «пустую коллекцию».
Лично должны быть два Tuple
, которые представляют одни и те же данные (например, («a», "b")
) не равно, потому что один имеет тип Tuple
, а другой - Tuple
?
Because of erasure you can't. About the best you could do is store in the tuple class the type you plan for the Tuple to hold in a "java.lang.Class" field member. Then you could compare those fields to make sure the tuple class is holding the same types.
Also see this thread:
Что эквивалентно C ++ Pair
Будет полезно, если вы разместите больше информации о своем классе. Я думаю, что непроверенное приведение и количество полей, которые вы приравниваете, означают, что это должно быть Tuple
РЕДАКТИРОВАТЬ: вот полезный класс Pair, который я регулярно использую (вы можете адаптировать свой класс Tuple при необходимости) . Обратите внимание: аналогично предложениям других, этот класс просто позволяет содержащимся в нем членам решать вопрос о равенстве. Ваш вариант использования - это то, что должно определить, действительно ли равенство основано на типе содержащихся в нем членов.
/**
* Adapted from http://forums.sun.com/thread.jspa?threadID=5132045
*
*
* @author Tim Harsch
*
* @param <L>
* @param <R>
*/
public class Pair<L, R> {
private final L left;
private final R right;
public R getRight() {
return right;
} // end getter
public L getLeft() {
return left;
} // end getter
public Pair(final L left, final R right) {
this.left = left;
this.right = right;
} // end constructor
public static <A, B> Pair<A, B> create(A left, B right) {
return new Pair<A, B>(left, right);
} // end factory method
@Override
public final boolean equals(Object o) {
if (!(o instanceof Pair<?,?>))
return false;
final Pair<?, ?> other = (Pair<?, ?>) o;
return equal(getLeft(), other.getLeft()) && equal(getRight(), other.getRight());
} // end method
public static final boolean equal(Object o1, Object o2) {
if (o1 == null) {
return o2 == null;
}
return o1.equals(o2);
} // end method
@Override
public int hashCode() {
int hLeft = getLeft() == null ? 0 : getLeft().hashCode();
int hRight = getRight() == null ? 0 : getRight().hashCode();
return hLeft + (37 * hRight);
} // end method
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('<');
if( left == null ) {
sb.append("null");
} else {
sb.append(left.toString());
} // end if
sb.append(',');
if( right == null ) {
sb.append("null");
} else {
sb.append(right.toString());
} // end if
sb.append('>');
return sb.toString();
} // end method
} // end class
Поскольку универсальные шаблоны стираются во время компиляции , вы можете в основном т. Во время выполнения любой параметр типа отсутствует, и что касается JVM, они во всех отношениях точно такие же.
Чтобы обойти это, можно сохранить поле Class
, представляющее тип, и создать объект с этим типом в конструкторе.
Пример конструктора:
public class Tuple < E > {
public Tuple(Class<E> c) {
//store the class
}
}
Или вы могли бы используйте фабрику:
public static <E> Tuple <E> getTuple(Class<E> type) {
// Create and return the tuple,
// just store that type variable in it
// for future use in equals.
}
The suggestions to retain a reference to E
's type with a Class
object seem inefficient (that's a lot of pointless references to a Class
taking up memory) and pointless for your problem.
It's not generally true that Foo
andFoo
should be unequal. So you don't need E
. And, in the code you wrote, you don't even need it to compile. Simply cast to Tuple>
, since that is truly all you know about Tuple
at that point. It still compiles and all.
If you are passed Tuple
s with data of two wildly different types, those elements will not be equals
, and your method will return false
, as desired. (One hopes -- depends on those types implementing equals
sanely.)
К сожалению, вы не можете сделать это во время компиляции; информация пропала. Таковы последствия стирания типа . В качестве альтернативы можно сохранить параметр как экземпляр Class
, а затем просмотреть его позже.
Off-topic - do you realise that according to your implementation, Tuple(a0, a1) is equal to Tuple(a1, a1)? I suspect that's not what you want...
On-topic, as others have said, erasure makes this impossible. But you should reconsider why you want this - equality checking only happens at runtime, and generics are only compile-time. Conceptually, a variable has generic parameters, but an object does not. Thus when you're comparing the equality of objects, the generic parameters do not matter at all; you can't take any appropriate action based on them at runtime anyway.
Object equality, and generic parameter co-/contra-variance, are two orthogonal concerns.
Я согласен с комментариями выше, почему класс E должен быть равен? и как вы хотите обрабатывать подклассы E?
В любом случае, учитывая, что вот пример кода, который может вам помочь:
public class Example<T> {
T t;
public Example(T t) {
this.t = t;
}
public static void main(String[] args) {
final String s = "string";
final Integer i = 1;
final Number n = 1;
final Example<String> exampleString = new Example<String>(s);
final Example<Integer> exampleInteger = new Example<Integer>(i);
final Example<Number> exampleNumber = new Example<Number>(n);
System.out.println("exampleString subclass " + exampleString.t.getClass());
System.out.println("exmapleIntger subclass " + exampleInteger.t.getClass());
System.out.println("exmapleNumber subclass " + exampleNumber.t.getClass());
System.out.println("Integer equals Number = " +
exampleInteger.t.equals(exampleNumber.t));
}
}
Вы можете вызвать t.getClass (), чтобы получить информацию о классе о типе T (при условии, что конечно, это не нуль.)
Надеюсь, это поможет.
Используйте отражение. http://tutorials.jenkov.com/java-reflection/generics.html