Определить некоторые классы POJO
JSON предназначен для чтения / десериализации в некоторые объекты. Таким образом Gson (или, альтернативно, Джексон) называется mapper . Они отображают JSON в POJO (простые старые Java объекты).
Итак, давайте определим модель. Для простоты используется Lombok (конструкторы, getter / setter, toString).
Item
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@Data
public class Item {
private String d1;
}
Контейнер (содержащий items )
Дополнительно использовал аннотацию Gson для соблюдения Java -naming-Convention (camelCase), пока разрешение указанных вами имен полей (в нижнем регистре).
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
public class Container {
@SerializedName("containertype")
private String containerType;
@SerializedName("item")
private List<Item> items;
@SerializedName("contenttype")
private String contentType;
}
Добавление функциональности к классу обслуживания
Отображение некоторых JSON в контейнеры
Использование типа -ссылка, чтобы сообщить Gson, какие объекты создавать.
Type containerListType = new TypeToken<ArrayList<Container>>(){}.getType();
gson = new Gson();
List<Container> containerList = gson.fromJson(json, containerListType);
Отфильтровать контейнеры, в которых есть элементы, соответствующие указанному критерию
, используя функционал Предикат и streaming (Java 8):
public static Predicate<Item> itemWhereD1equalsSt = item -> "St".equals(item.getD1());
public static Predicate<Container> containerHasItemsWhereD1equalsSt = container -> {
List<Item> items = container.getItems();
if (items != null) {
boolean hasItemMatching = items.stream().anyMatch(itemWhereD1equalsSt);
return hasItemMatching;
}
return false;
};
public List<Container> filterFromJson(List<Container> containerList, Predicate<Container> containerPredicate) {
return containerList.stream()
.filter(containerPredicate)
.collect(Collectors.toList());
}
Удаляет элементы, соответствующие указанному критерию
, используя функционал на основе потока и удобный метод в List (Java 8):
(a) Простой вариант (предикат, встроенный с использованием лямбда-выражения ):
public void removeItemsSimple(List<Container> containers) {
for (Container container : containers) {
container.getItems().removeIf(item -> item.getD1().equalsIgnoreCase("St"));
}
}
(b) Улучшенный вариант (передайте в качестве параметра предикат, который мы уже использовали с контейнерами):
public List<Item> removeItemsBasedOnFilter(List<Container> containers, Predicate<Item> itemPredicate) {
return containers.stream()
.flatMap(container -> removeItemsBasedOnFilter(container, itemPredicate).stream())
.collect(Collectors.toList());
}
public List<Item> removeItemsBasedOnFilter(Container container, Predicate<Item> itemPredicate) {
// Optional: filter all items in container that should be removed
List<Item> itemsToBeRemoved = container.getItems().stream()
.filter(itemPredicate)
.collect(Collectors.toList());
// remove all items that match the predicate
container.getItems().removeIf(itemPredicate);
// Optional: return removed items
return itemsToBeRemoved;
}
Полный сервис e-class
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class JsonFilter {
private static final Type containerListType = new TypeToken<ArrayList<Container>>(){}.getType();
public static Predicate<Item> itemWhereD1equalsSt = item -> "St".equals(item.getD1());
public static Predicate<Container> containerHasItemsWhereD1equalsSt = container -> {
List<Item> items = container.getItems();
if (items != null) {
boolean hasItemMatching = items.stream().anyMatch(itemWhereD1equalsSt);
return hasItemMatching;
}
return false;
};
private final Gson gson;
public JsonFilter() {
gson = new Gson();
}
public List<Container> readContainers(String json) {
List<Container> containerList = gson.fromJson(json, containerListType);
return containerList;
}
public List<Container> filterFromJson(List<Container> containerList, Predicate<Container> containerPredicate) {
return containerList.stream()
.filter(containerPredicate)
.collect(Collectors.toList());
}
public void removeItemsSimple(List<Container> containers) {
for (Container container : containers) {
container.getItems().removeIf(item -> item.getD1().equalsIgnoreCase("St"));
}
}
public List<Item> removeItemsBasedOnFilter(List<Container> containers, Predicate<Item> itemPredicate) {
return containers.stream()
.flatMap(container -> removeItemsBasedOnFilter(container, itemPredicate).stream())
.collect(Collectors.toList());
}
public List<Item> removeItemsBasedOnFilter(Container container, Predicate<Item> itemPredicate) {
// Optional: filter all items in container that should be removed
List<Item> itemsToBeRemoved = container.getItems().stream()
.filter(itemPredicate)
.collect(Collectors.toList());
// remove all items that match the predicate
container.getItems().removeIf(itemPredicate);
// Optional: return removed items
return itemsToBeRemoved;
}
}
Проверено
с использованием JUnit5 без утверждений - просто печать на консоль.
import org.junit.jupiter.api.Test;
import java.util.List;
class JsonFilterTest {
@Test
void filterContainerList() {
final String json = givenJson(); // your test-data
final JsonFilter jsonFilter = new JsonFilter();
// map JSON to a list of containers
List<Container> containersRead = jsonFilter.readContainers(json);
// first filter-out all containers that do not have specified items
List<Container> containersFiltered = jsonFilter.filterFromJson(containersRead, JsonFilter.containerHasItemsWhereD1equalsSt);
System.out.println("Filtered containers resulting: " + containersFiltered.size());
// then remove specified items from these resulting containers
List<Item> itemsRemoved = jsonFilter.removeItemsBasedOnFilter(containersFiltered, JsonFilter.itemWhereD1equalsSt);
System.out.println("Removed items: " + itemsRemoved.size());
}
private String givenJson() {
return "[\n" +
" {\n" +
" \"containertype\": \"check2\",\n" +
" \"item\": [\n" +
" {\n" +
" \"d1\": \"St\"\n" +
" },\n" +
" {\n" +
" \"d1\": \"Pt\"\n" +
" },\n" +
" {\n" +
" \"d1\": \"St\"\n" +
" }\n" +
" ],\n" +
" \"contenttype\": \"test\"\n" +
" },\n" +
" {\n" +
" \"containertype\": \"check2\",\n" +
" \"item\": [\n" +
" {\n" +
" \"d1\": \"Pt\"\n" +
" },\n" +
" {\n" +
" \"d1\": \"Pt\"\n" +
" },\n" +
" {\n" +
" \"d1\": \"Pt\"\n" +
" }\n" +
" ],\n" +
" \"contenttype\": \"test\"\n" +
" }\n" +
"]";
}
}