Skip to content

Commit 75959f6

Browse files
replace stream api usage on Map with dedicated for loop
1 parent a682ef9 commit 75959f6

File tree

3 files changed

+73
-5
lines changed

3 files changed

+73
-5
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -674,12 +674,13 @@ public <T> T getPropertyValue(MongoPersistentProperty property) {
674674
}
675675

676676
if (!documentField.getProperty().isMap() && sourceValue instanceof Document document) {
677-
return new Document(document.entrySet().stream().collect(Collectors.toMap(Entry::getKey, entry -> {
678-
if (isKeyword(entry.getKey())) {
679-
return getMappedValue(documentField, entry.getValue());
677+
678+
return BsonUtils.mapValues(document, (key, val) -> {
679+
if (isKeyword(key)) {
680+
return getMappedValue(documentField, val);
680681
}
681-
return entry.getValue();
682-
})));
682+
return val;
683+
});
683684
}
684685

685686
return valueConverter.write(value, conversionContext);

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@
2020
import java.util.Collection;
2121
import java.util.Collections;
2222
import java.util.Date;
23+
import java.util.LinkedHashMap;
2324
import java.util.List;
2425
import java.util.Map;
26+
import java.util.Map.Entry;
2527
import java.util.StringJoiner;
28+
import java.util.function.BiFunction;
2629
import java.util.function.Function;
2730
import java.util.stream.StreamSupport;
2831

@@ -716,6 +719,23 @@ public static Collection<?> asCollection(Object source) {
716719
return source.getClass().isArray() ? CollectionUtils.arrayToList(source) : Collections.singleton(source);
717720
}
718721

722+
public static Document mapValues(Document source, BiFunction<String, Object, Object> valueMapper) {
723+
return mapEntries(source, Entry::getKey, entry -> valueMapper.apply(entry.getKey(), entry.getValue()));
724+
}
725+
726+
public static Document mapEntries(Document source, Function<Entry<String,Object>,String> keyMapper, Function<Entry<String,Object>,Object> valueMapper) {
727+
728+
if(source.isEmpty()) {
729+
return source;
730+
}
731+
732+
Map<String, Object> target = new LinkedHashMap<>(source.size(), 1f);
733+
for(Entry<String,Object> entry : source.entrySet()) {
734+
target.put(keyMapper.apply(entry), valueMapper.apply(entry));
735+
}
736+
return new Document(target);
737+
}
738+
719739
@Nullable
720740
private static String toJson(@Nullable Object value) {
721741

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/util/json/BsonUtilsTest.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.LinkedHashMap;
3030
import java.util.List;
3131
import java.util.Map;
32+
import java.util.Map.Entry;
3233
import java.util.stream.Stream;
3334

3435
import org.bson.BsonArray;
@@ -180,6 +181,52 @@ void resolveValueForField(FieldName fieldName, boolean exists) {
180181
}
181182
}
182183

184+
@Test
185+
void retainsOrderWhenMappingValues() {
186+
187+
Document source = new Document();
188+
source.append("z", "first-entry");
189+
source.append("a", "second-entry");
190+
source.append("0", "third-entry");
191+
source.append("9", "fourth-entry");
192+
193+
Document target = BsonUtils.mapValues(source, (key, value) -> value);
194+
assertThat(source).isNotSameAs(target).containsExactlyEntriesOf(source);
195+
}
196+
197+
@Test
198+
void retainsOrderWhenMappingKeys() {
199+
200+
Document source = new Document();
201+
source.append("z", "first-entry");
202+
source.append("a", "second-entry");
203+
204+
Document target = BsonUtils.mapEntries(source, entry -> entry.getKey().toUpperCase(), Entry::getValue);
205+
assertThat(target).containsExactly(Map.entry("Z", "first-entry"), Map.entry("A", "second-entry"));
206+
}
207+
208+
@Test
209+
void appliesValueMapping() {
210+
Document source = new Document();
211+
source.append("z", "first-entry");
212+
source.append("a", "second-entry");
213+
214+
Document target = BsonUtils.mapValues(source,
215+
(key, value) -> new StringBuilder(value.toString()).reverse().toString());
216+
assertThat(target).containsValues("yrtne-tsrif", "yrtne-dnoces");
217+
}
218+
219+
@Test
220+
void appliesKeyMapping() {
221+
222+
Document source = new Document();
223+
source.append("z", "first-entry");
224+
source.append("a", "second-entry");
225+
226+
Document target = BsonUtils.mapEntries(source, entry -> entry.getKey().toUpperCase(), Entry::getValue);
227+
assertThat(target).containsKeys("Z", "A");
228+
}
229+
183230
static Stream<Arguments> fieldNames() {
184231
return Stream.of(//
185232
Arguments.of(FieldName.path("a"), true), //

0 commit comments

Comments
 (0)