在Java中序列化Lambda表达式(Predicate/BiPredicate)。

huangapple go评论99阅读模式
英文:

Serializing lambda expression java (predicate/bipredicate)

问题

我目前正试图编写一个关于我的游戏对话例程的泛化版本(当前情况下,每个NPC角色都有自己的类,我必须在其中硬编码一堆if-else语句)。

为了做到这一点,我正在编写一个表示对话的对话树类(DialogueTree)。对话树由包含许多字段的节点(Nodes)组成,但在这里重要的一个字段是BiPredicate 'req',它表示玩家和NPC的要求(统计数据、任务等),玩家要遵循这个对话路径。以下是到目前为止的所有代码。

public class DialogueTree implements Serializable {

    private Node head;

    public DialogueTree() {
        head = new Node((p, q) -> true);
    }

    public DialogueTree add(int[] path, BiPredicate<Player, NPC> req) {
        head.children.add(new Node(req));
        return this;
    }

    private static class Node implements Serializable {
        public List<Node> children;
        public BiPredicate<Player, NPC> req;

        public Node(BiPredicate<Player, NPC> req) {
            this.req = req;
        }
    }
}

我省略了很多代码,因为我不想分散注意力,但我想要强调的主要是,在构建这些对话树时,我正在传递Lambda表达式(我这样做的主要原因是我不想为每个NPC的对话编写一个新的类,因此我不想编写一个实现BiPredicate和Serializable接口的特定要求的类)。

问题是,当我启动游戏并尝试保存时,游戏崩溃并引发错误,指出Lambda表达式不可序列化。我尝试在Node构造函数中将req强制转换为Serializable:

this.req = (BiPredicate<Player, NPC> & Serializable) req;

但这给我带来了一个类强制转换异常。任何帮助都会非常感激:D

英文:

I am currently attempting to write a generalization of dialogue routines for my game (currently, every npc character has their own class where i have to hardcode in a bunch of if-else statements)

to do so, I am writing a class DialogueTree which represents the dialogue. A dialogue tree is made up of Nodes which contain many fields, but the important one here is a BiPredicate 'req', which represents the requirements (stat, quest etc) of the player and npc for the player to go down this dialogue path. Here is the code for all of that so far.

public class DialogueTree implements Serializable {

    private Node head;

	public DialogueTree() {
		head = new Node((p,q) -&gt; true);
	}

	public DialogueTree add(int[] path, BiPredicate&lt;Player,NPC&gt; req) {
		head.children.add(new Node(req));
		return this;
	}

    private static class Node implements Serializable {
		public List&lt;Node&gt; children;
		public BiPredicate&lt;Player,NPC&gt; req;
			
		public Node(BiPredicate&lt;Player,NPC&gt; req) {
		   this.req = req;
		}
	}
}

i left out a lot of the code because i don't want to distract with irrelevant details, but the main thing i wanna highlight is that when constructing these DialogueTrees i'm passing in lambda expressions (the whole reason im doing this is so I don't have to write a new class for every single NPC's dialogue, so I don't want to write a class for a specific requirement that implements BiPredicate and Serializable)

the issue is have is when i start the game and try to save, the game crashes with an error citing the lambda expression as non-serializable. i tried casting req to serializable within the Node constructor

this.req = (BiPredicate&lt;Player,NPC&gt; &amp; Serializable)req;

however that got me a class cast exception.

any help is greatly appreciate 在Java中序列化Lambda表达式(Predicate/BiPredicate)。

答案1

得分: 1

抱歉,代码部分不需要翻译,以下是要翻译的内容:

"The cast is failing because the BiPredicate was already instantiated with a non-Serializable lambda. To make it serializable, you need to cast the lambda expression itself:

head = new Node((BiPredicate<Player,NPC> & Serializable)(p,q) -> true);"

英文:

The cast is failing because the BiPredicate was already instantiated with a non-Serializable lambda. To make it serializable, you need to cast the lambda expression itself:

head = new Node((BiPredicate&lt;Player,NPC&gt; &amp; Serializable)(p,q) -&gt; true);

Ideone Demo

huangapple
  • 本文由 发表于 2023年8月4日 05:24:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76831692.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定