diff --git a/src/main/java/ch/njol/skript/lang/Variable.java b/src/main/java/ch/njol/skript/lang/Variable.java
index 1b7a55f42b6..173ee1aeea3 100644
--- a/src/main/java/ch/njol/skript/lang/Variable.java
+++ b/src/main/java/ch/njol/skript/lang/Variable.java
@@ -1,23 +1,10 @@
-/**
- * This file is part of Skript.
- *
- * Skript is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Skript is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Skript. If not, see .
- *
- * Copyright Peter Güttinger, SkriptLang team and contributors
- */
package ch.njol.skript.lang;
+import java.lang.reflect.Array;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.function.Function;
+
import ch.njol.skript.Skript;
import ch.njol.skript.SkriptAPIException;
import ch.njol.skript.SkriptConfig;
@@ -55,17 +42,6 @@
import org.skriptlang.skript.lang.script.Script;
import org.skriptlang.skript.lang.script.ScriptWarning;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.NoSuchElementException;
-import java.util.TreeMap;
-import java.util.function.Function;
-
public class Variable implements Expression {
private final static String SINGLE_SEPARATOR_CHAR = ":";
@@ -579,14 +555,15 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) throw
if (mode == ChangeMode.REMOVE) {
if (map == null)
return;
- ArrayList toRemove = new ArrayList<>(); // prevents CMEs
+ Set toRemove = new HashSet<>(); // prevents CMEs
for (Object value : delta) {
for (Entry entry : map.entrySet()) {
+ String key = entry.getKey();
+ if (key == null)
+ continue; // This is NOT a part of list variable
+ if (toRemove.contains(key))
+ continue; // Skip if we've already marked this key to be removed
if (Relation.EQUAL.isImpliedBy(Comparators.compare(entry.getValue(), value))) {
- String key = entry.getKey();
- if (key == null)
- continue; // This is NOT a part of list variable
-
// Otherwise, we'll mark that key to be set to null
toRemove.add(key);
break;
@@ -600,7 +577,7 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) throw
} else if (mode == ChangeMode.REMOVE_ALL) {
if (map == null)
return;
- ArrayList toRemove = new ArrayList<>(); // prevents CMEs
+ Set toRemove = new HashSet<>(); // prevents CMEs
for (Entry i : map.entrySet()) {
for (Object value : delta) {
if (Relation.EQUAL.isImpliedBy(Comparators.compare(i.getValue(), value)))
diff --git a/src/test/skript/tests/regressions/7162-removing from variable skips duplicates.sk b/src/test/skript/tests/regressions/7162-removing from variable skips duplicates.sk
new file mode 100644
index 00000000000..c4fadc84163
--- /dev/null
+++ b/src/test/skript/tests/regressions/7162-removing from variable skips duplicates.sk
@@ -0,0 +1,6 @@
+test "removing from variables skips duplicates":
+ set {_list::*} to 1, 1, 2, 3, 4, 5, 6 and 6
+ remove 1 and 1 from {_list::*}
+ assert {_list::*} is 2, 3, 4, 5, 6 and 6 with "didn't remove all instances of 1 from the list"
+ remove first 6 elements out of {_list::*} from {_list::*}
+ assert {_list::*} is not set with "didn't remove all elements"