#java #union #awt
#java #объединение #awt
Вопрос:
У меня есть список прямоугольников AWT. Я хочу вычислить объединение прямоугольников элегантным способом. Вот мой код, который работает, но выглядит не очень элегантно.
Rectangle union(List<Rectangle> rects) {
if (rects.isEmpty()) {
return new Rectangle();
}
assert !rects.isEmpty();
final Iterator<Rectangle> iterator = rects.iterator();
Rectangle rect = iterator.next();
while (iterator.hasNext()) {
rect = rect.union( iterator.next() );
}
return rect;
}
Я также попробовал следующее, которое не работает:
Rectangle union(List<Rectangle> rects) {
Rectangle result = new Rectangle();
for (Rectangle rect : rects) {
result.add( rect );
}
return resu<
}
Результат rectangle инициализируется значением (0,0,0,0), поэтому объединение всегда будет содержать начало координат.
Есть ли более элегантный способ сделать это на Java?
Комментарии:
1. Почему вы используете
union()
в первом коде иadd()
во втором? Я предполагаю, что именно из-за этой разницы это не работает…
Ответ №1:
Во втором примере вам нужно инициализировать result
следующим образом:
Rectangle result = new Rectangle(-1, -1);
Имейте в виду, что это работает только начиная с Java SE 6. В предыдущих версиях поведение в отношении отрицательных ширин и высот не определено. Аналогичный пример с набором точек смотрите в записи Javadoc для Rectangle
.
Ответ №2:
Я думаю, что ваше решение неплохое. Вот как я бы это сделал:
public static void main(String[] args) {
List<Rectangle> rects = new ArrayList<Rectangle>();
rects.add(new Rectangle(new Point(1, 1), new Dimension(3, 4)));
rects.add(new Rectangle(new Point(2, 2), new Dimension(5, 7)));
Rectangle u = union(rects);
Rectangle a = add(rects);
System.out.println(u);
System.out.println(a);
}
public static Rectangle union(List<Rectangle> rects) {
if (rects.isEmpty())
throw new IllegalArgumentException();
Rectangle unionRectangle = new Rectangle(rects.get(0));
for (int i = 1; i < rects.size(); i )
unionRectangle = unionRectangle.union(rects.get(i));
return unionRectangle;
}
public static Rectangle add(List<Rectangle> rects) {
if (rects.isEmpty())
throw new IllegalArgumentException();
Rectangle unionRectangle = new Rectangle(rects.get(0));
for (int i = 1; i < rects.size(); i )
unionRectangle.add(rects.get(i));
return unionRectangle;
}
Вывод является
java.awt.Rectangle[x=1,y=1,width=6,height=8]
java.awt.Rectangle[x=1,y=1,width=6,height=8]
Некоторые примечания:
-
Если список
rects
пуст, я бы выдал исключение, а не возвращалRectangle
-
оба
Rectangle.union
иRectangle.add
дают одинаковые результаты (см. Выходные данные) -
Я бы начал с нового,
Rectangle
равного первому элементуrects
, а затем использовал его для вычисления объединения со следующими (или, что эквивалентно, добавил следующие).
Я надеюсь, что это поможет.
Ответ №3:
Согласно прилагаемому javadoc, ваш add
основанный должен работать. В нем говорится:
Добавляет прямоугольник к этому прямоугольнику. Результирующий прямоугольник является объединением двух прямоугольников.
Но это работает только при инициализации прямоугольника с размером, меньшим нуля. Вот рабочее решение для метода 2:
Rectangle union(List<Rectangle> rects) {
Rectangle result = new Rectangle(-1,-1); // dimension less than 0
for (Rectangle rect : rects) {
result.add( rect );
}
return resu<
}
Альтернатива: создайте исходный результат на основе первого элемента списка:
Rectangle union(List<Rectangle> rects) {
if (rects == null || rects.isEmpty()) return null;
Rectangle result = new Rectangle(rects.get(0));
for (Rectangle rect : rects) {
result.add( rect );
}
return resu<
}