Какие объекты хранятся в ValueStack

Это мой код ниже, когда я выполняю, он показывает мне размер 3, но когда я выталкиваю объект, я получаю только 2 объекта.

import java.util.*;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport {

    private static final long serialVersionUID = 1L;
    private String name;

    public String execute() throws Exception {
        ValueStack stack = ActionContext.getContext().getValueStack();
        Map<String, Object> context = new HashMap<String, Object>();

        context.put("key1", new String("This is key1"));
        context.put("key2", new String("This is key2"));
        context.put("key3", new String("This is key3"));
        stack.push(context);

        System.out.println("Size of the valueStack: " + stack.size());

        for (int i = 0; i < stack.size(); i++) {
            System.out.println(i + ": " + stack.pop().toString());
        }
        return "success";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
 

Пожалуйста, объясните мне, я делаю это неправильно?

Я хочу знать, какие объекты хранятся в ValueStack и как я могу получить эти объекты?


person Sachin Singh    schedule 01.08.2016    source источник
comment
Вы помещаете один объект в стек значений: context :|   -  person Andrea Ligios    schedule 01.08.2016
comment
да, я нажимаю только один объект, а другой объект в стеке значений - это объект действия, поэтому это означает, что есть только 2 объекта, поэтому размер стека значений должен быть 2, но он дает мне 3 как размер объекта, вот что меня беспокоит, я хочу знать, почему он показывает размер 3?   -  person Sachin Singh    schedule 01.08.2016
comment
В стеке значений есть несколько вещей. Например, само действие помещается в стек перед попаданием в слой представления.   -  person Dave Newton    schedule 01.08.2016


Ответы (2)


Вы плохо обращались с context и картой.

Во-первых, у вас есть действие context и valueStack.

Затем вы создали карту с именем context и поместили ее в стек.

Затем вы начали перебирать стек, но стек — это другой объект, который был context передвинут.

Чтобы вернуть контекст из стека, вам нужно pop() или peek() его из файла valueStack. Затем вы можете повторить его как карту.

Код:

context = (Map<String, Object>)stack.pop();
for (Map.Entry<String, Object> entry : context.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

person Roman C    schedule 01.08.2016
comment
на самом деле ты меня неправильно понял. я хочу сказать, что когда я печатаю размер объекта, он дает 3 в качестве вывода, но когда я выталкиваю объект из стека значений, я получаю только 2 объекта. На самом деле хочу понять, какие объекты хранятся в стеке значений, и я получаю только 2 объекта - person Sachin Singh; 01.08.2016
comment
вы печатаете размер стека, а не размер объекта в стеке - person Roman C; 01.08.2016
comment
используя stack.pop(), я пытаюсь получить объект в стеке. но в любом случае спасибо я получил ответ - person Sachin Singh; 01.08.2016
comment
Вы должны получить ( pop() ) единственный объект, который вы нажали, вот в чем дело. - person Roman C; 01.08.2016
comment
@SachinSingh не так ли? дайте ссылку или может быть кто-то уже спрашивал об этом раньше? - person Roman C; 01.08.2016
comment
спасибо за эту информацию, сэр. но в спецификации ничего подобного не упоминается struts.apache.org/maven/struts2-core/apidocs/com/opensymphony/ - person Sachin Singh; 01.08.2016
comment
valueStack обычно используется на уровне представления, поэтому важно использовать объект pop(), когда он больше не нужен. Это краткое описание, более подробное объяснение вы можете найти в этом ответе. - person Roman C; 01.08.2016
comment
@SachinSingh Примите ответ. - person Roman C; 29.10.2016

В вашем коде есть две ошибки, которые мешают правильно распечатать результат.


Ошибка № 1

i <= stack.size() должно быть i < stack.size(), иначе с 3 элементами вы попытаетесь напечатать 4 элемента (i основано на 0, size() основано на 1).
Эта ошибка возникает не из-за ошибки n.2.


Ошибка №2

System.out.println(i + ": " + stack.pop().toString());

.pop() : получить объект на вершине стека и удалить его из стека.

Затем вы должны сохранить размер перед циклом, потому что в противном случае размер стека изменяется при каждой итерации.

Вот что происходит:

for (int i = 0; i <= 3; i++) {

for (int i = 1; i <= 2; i++) {

for (int i = 2; i <= 1; i++) { // not performed. And you don't fall in error n.1.

Рабочий код(ы)

int size = stack.size();

for (int i = 0; i < size; i++) {
    System.out.println(i + ": " + stack.pop().toString());
}

Это позволит правильно распечатать результат, однако изменит стек значений; чтобы предотвратить это, вы должны зациклить объекты стека значений внутри итератора, который вы можете получить с помощью метода getRoot():

Iterator itr = stack.getRoot().iterator();
while (itr.hasNext()) {
    System.out.println(itr.next().toString()); 
    // or .getClass().getName(), ReflectionToStringBuilder.toString(), or whatever...
}
person Andrea Ligios    schedule 01.08.2016
comment
спасибо, что указали на это, но это то, что я пытаюсь проверить, выдает ли оно какое-либо исключение или нет, и вы будете рады узнать, что оно не выдавало никаких исключений. еще одна вещь, которую вам нужно отметить, это то, что я не использую i, а peek возвращает только самый верхний элемент в стеке. - person Sachin Singh; 01.08.2016
comment
спасибо, приятель, но в случае pop() также не будет исключений. но это не было моей заботой, и я получил свой ответ, используя метод getroot(), и он дал мне 3 объекта, которые находятся в стеке значений, и это [{key3=Это ключ3, ключ2=Это ключ2, ключ1=Это is key1}, com.sachin.HelloWorldAction@4e857327, com.opensymphony.xwork2.DefaultTextProvider@1b4b2db7] спасибо за помощь - person Sachin Singh; 01.08.2016
comment
@SachinSingh У вас есть тот же объект, и его размер не изменился, потому что valueStack является потокобезопасным. Вы просто используете другой метод для извлечения объекта, но API тот же, за исключением того, что вы получили много ошибок в программировании кода Java. - person Roman C; 01.08.2016
comment
Не знаю, почему он не получает 3-й элемент, и почему он не пытается получить несуществующий 4-й, а затем @RomanC. Но все вопросы и ответы сбивают с толку, так что это может быть все - person Andrea Ligios; 01.08.2016
comment
@AndreaLigios ты прав. размер целого числа = стек.размер(); for (int i = 0; i ‹ size; i++) { System.out.println(i + : + stack.pop().toString()); } это то, что я использовал в своем приложении, и я не пытался получить 4-й элемент, я просто проверял, выдает ли он исключение или нет. Я собираюсь отредактировать приведенный выше код, чтобы он не отвлекал других людей. Даже если вы можете попробовать, вы также получите 2 элемента, даже если размер стека значений показывает 3. В любом случае, спасибо за вашу помощь. - person Sachin Singh; 01.08.2016
comment
@AndreaLigios Часть, в которой используется цикл for, неверна и должна быть удалена, вопрос действительно раскрывает проблему XY и будет закрыт как не по теме. - person Roman C; 01.08.2016
comment
@RomanC: Я пытался, как я и сказал. Это был выстрел в темноте, но если подумать, stack.size() возвращает не размер стека, а возвращает размер внутреннего CompoundRoot. Если он изменяется, на каждой итерации для размера возвращается новое значение. Вы получите ConcurrentModificationException при повторении списков/карт и удалении элементов из коллекции, которую вы итерируете; вместо этого со стеком значений вы получаете этот нежелательный результат:) - person Andrea Ligios; 01.08.2016
comment
@SachinSingh, пожалуйста, не забывайте проголосовать за каждый полезный ответ и принять ответ, который полностью решил вашу проблему, если таковой имеется. Спасибо - person Andrea Ligios; 01.08.2016