【问题标题】:How to filter list of data in list in java with sql or nested dynamic conditionjava - 如何使用sql或嵌套动态条件过滤java中列表中的数据列表
【发布时间】:2021-02-11 09:59:19
【问题描述】:

如何使用java动态过滤数据,假设我们有数据(没有pojo映射的map/json数组列表)。

[
  {
    "id": "1001",
    "type": "Internal",
    "status": "Closed"
  },
  {
    "id": "1002",
    "type": "External",
    "status": "Closed"
  },
  {
    "id": "1003",
    "type": "Internal",
    "status": "Open"
  },
  {
    "id": "1004",
    "type": "Internal",
    "status": "Open"
  }
]

现在我们需要将过滤后的数据输出为id > 1001 and ( type: 'External' or status: 'Open" )

 [ 
  {
    "id": "1002",
    "type": "External",
    "status": "Closed"
  },
  {
    "id": "1003",
    "type": "Internal",
    "status": "Open"
  },
  {
    "id": "1004",
    "type": "Internal",
    "status": "Open"
  } 
]

任何建议如何实现这一目标?

【问题讨论】:

  • 我最多说我很困惑,你想从原始json中提取数据吗?来自对象列表的数据库?您尝试了哪些方法,您在哪里遇到问题?
  • @S_R 已经发布了一个答案,看看这是否是你所要求的。

标签: java json lambda filter predicate


【解决方案1】:

使用 JSON 路径,下面是我作为示例发布的几个 JSONPath 查询

P.S :- Ur "Id" 应该是整数类型以进行操作 > 或 <

代码:-

public static void main(String[] args) {
    String jsonData = "[\r\n" + 
            "  {\r\n" + 
            "    \"id\": 1001,\r\n" + 
            "    \"type\": \"Internal\",\r\n" + 
            "    \"status\": \"Closed\"\r\n" + 
            "  },\r\n" + 
            "  {\r\n" + 
            "    \"id\": 1002,\r\n" + 
            "    \"type\": \"External\",\r\n" + 
            "    \"status\": \"Closed\"\r\n" + 
            "  },\r\n" + 
            "  {\r\n" + 
            "    \"id\": 1003,\r\n" + 
            "    \"type\": \"Internal\",\r\n" + 
            "    \"status\": \"Open\"\r\n" + 
            "  },\r\n" + 
            "  {\r\n" + 
            "    \"id\": 1004,\r\n" + 
            "    \"type\": \"Internal\",\r\n" + 
            "    \"status\": \"Open\"\r\n" + 
            "  }\r\n" + 
            "]";
    
    String filterId = "$.[?(@.id > 1001)]"; //For Id > 1001
    String filterType =  "$.[?(@.type in ['External'])]"; //for External type
    String filterTypeAndId =  "$.[?((@.id > 1001) && (@.type in ['Internal']))]"; //for External type with Id > 1001
    String filterTypeAndId2 =  "$.[?((@.id > 1001) && (@.type in ['Internal', 'External']))]"; //for External type with Id > 1001
    DocumentContext documentContext = JsonPath.parse(jsonData);
    System.out.println(documentContext.read(filterId).toString());
    System.out.println(documentContext.read(filterType).toString());
    System.out.println(documentContext.read(filterTypeAndId).toString());
    System.out.println(documentContext.read(filterTypeAndId2).toString());
}

结果是:-

[{"id":1002,"type":"External","status":"Closed"},{"id":1003,"type":"Internal","status":"Open"},{"id":1004,"type":"Internal","status":"Open"}]

[{"id":1002,"type":"External","status":"Closed"}]

[{"id":1003,"type":"Internal","status":"Open"},{"id":1004,"type":"Internal","status":"Open"}]

[{"id":1002,"type":"External","status":"Closed"},{"id":1003,"type":"Internal","status":"Open"},{"id":1004,"type":"Internal","status":"Open"}]

【讨论】:

    【解决方案2】:

    我们可以使用 javascript 的能力来解决条件。我们可以使用 Java ScriptEngineManager 来运行 javascript 表达式: 表达式可以是type = 'Internal' AND status ='Open'

        private String getResult(String expression) {
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("JavaScript");
            try {
                return engine.eval(expression).toString();
            } catch (Exception e) {
            }
            return null;
        }

    【讨论】:

      【解决方案3】:

      您可以通过以下方法实现这一点:-

      1. json转字符串
      2. 构造 JSONArray >> JSONArray jsonArray = new JSONArray(converted_json_String)
      3. 从JsonArray中取出jsonArrayObject并构造一个列表
      4. 使用 Collections.sort 方法并将您的比较逻辑部署在 JSON 键上 并构建您的排序 json。

      【讨论】:

        【解决方案4】:

        试试这段代码,我假设你有一个对象列表。

        List<YourCLass> filteredList = list
                            .stream()
                            .filter(obj -> obj.getId() > 1001 && (obj.getStatus().equals("Open") || obj.getType().equals("External")))
                            .collect(Collectors.toList());
        

        filteredList 有你期望的对象列表,使用 Object mapper 你可以得到它的 json 格式。

        String filteredObjJson = new ObjectMapper().writeValuesAsString(filteredList);
        

        在 pom.xml 中添加此依赖项或下载 lib 并将其添加到您的库中

        <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
        </dependency>
        

        【讨论】:

        • 需要在没有POJO映射的情况下实现这个。
        • 有可能,试试这个link。这是有那个解决方案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-12
        相关资源
        最近更新 更多