我有一个静态地图如下:
private static final Map<String, String> queries;
static {
Map<String, String> tmpMap = new HashMap<>();
tmpMap.put("USER_WITHOUT_ROLE_QUERY","...");
tmpMap.put("PROFIL_WITHOUT_ROLE_QUERY","...");
//Removed code for readability
queries = Collections.unmodifiableMap(tmpMap);
}
以下两个String数组:
String[] typeFilter
可以包含以下值的组合:
[&#34; WITHOUT_PROFIL&#34;,&#34; WITHOUT_ROLE&#34;,&#34; WITHOUT_USER&#34;]; String[] elementFilter
可以包含以下值的组合:[&#34; PROFIL&#34;,
&#34;角色&#34;,&#34; UTILISATEUR&#34;]; 我想要做的是取决于typeFilter
和elementFilter
中的值来过滤queries
地图,并使用" UNION "
加入过滤后的地图的值。< / p>
例如,如果typeFilter
包含"WITHOUT_ROLE"
而elementFilter
包含"PROFIL"
和"USER"
,则过滤后的地图将只包含PROFIL_WITHOUT_ROLE_QUERY
和{{1}因此,结果将是:USER_WITHOUT_ROLE_QUERY
。
这就是我的尝试:
queries.get("PROFIL_WITHOUT_ROLE_QUERY") + " UNION " + queries.get("USER_WITHOUT_ROLE_QUERY")
我该如何解决这个问题?是否有更好的方法来执行上述代码?
答案 0 :(得分:0)
您可以尝试以下操作。
List<String> queriesToJoin = queries.entrySet().stream().filter(e -> queriesMapKeys.contains(e.getKey())).collect(Collectors.toList());
String sqlQuery = String.join(" UNION ", queriesToJoin);
答案 1 :(得分:0)
您不必使用流。您可以使用StringJoiner
类:
import java.util.StringJoiner;
<...>
StringJoiner builder = new StringJoiner(" UNION ");
for (String element : elementFilter) {
for (String type : typeFilter) {
String key = element + "_" + type + "_QUERY";
if (queries.containsKey(key)) {
builder.add(queries.get(key));
}
}
}
String sqlQuery = builder.toString();
琐事:StringJoiner
类是您在执行String::join
时从内部使用的内容,或使用Stream
从Collectors.joining
收集的内容。
答案 2 :(得分:0)
您似乎只想从地图中获取一组键的值。这将是一条直线:
List<String> queriesToJoin = queries
.entrySet()
.stream()
.filter(e -> queriesMapKeys.contains(e.getKey()))
.map(Map.Entry::getValue)
.collect(Collectors.toList());
您还需要一种更好的方法来实现它。
使用格式化字符串为查询和过滤器的某些属性建模。您可以尝试的是使用类或谓词来执行此操作。
例如,不要使用字符串作为查询的键/名称,而应考虑使用枚举。
public enum QueryId {
USER_WITHOUT_ROLE_QUERY(USER, WITHOUT_ROLE),
PROFIL_WITHOUT_ROLE_QUERY(PROFIL, WITHOUT_ROLE);
QueryId(TargetElement element, QueryType type) {...}
public TargetElement getElement() {...}
public QueryType getQueryType() {...}
}
然后,您可以使用QueryId.getElement()
或QueryId.getQueryType()
。
答案 3 :(得分:0)
如果要将第一个嵌套循环与过滤地图的代码合并
,请尝试使用此方法String[] queriesToJoin = Arrays.asList(elementFilter)
.stream()
.flatMap(f -> Arrays.asList(typeFilter)
.stream()
.map(s -> f + "_" + s + "_QUERY"))
.filter(t -> queries.containsKey(t))
.map(t -> queries.get(t))
.collect(Collectors.toList()).toArray(new String [0]);
答案 4 :(得分:0)
在您的代码中
// Filter queries map
List<String> queriesMapKeys = new ArrayList<>();
for (String element : elementFilter) {
for (String type : typeFilter) {
queriesMapKeys.add(queries.get(element + "_" + type + "_QUERY"));
}
}
您已经在查询地图并将get
的结果添加到queriesMapKeys
列表中。如果某个键不在地图中,则null
引用将显示在列表中。密钥在该列表中不可用。因此,执行另一个流操作尝试将列表与地图键匹配,如
String[] queriesToJoin = queries.entrySet().stream()
.filter(e -> queriesMapKeys.contains(e.getKey())) …
根本无法运作。
但无论如何都没有必要。您只需处理潜在的null
值。之一:
queriesMapKeys.removeIf(Objects::isNull);
String sqlQuery = String.join(" UNION ", queriesMapKeys);
或
String sqlQuery = queriesMapKeys.stream()
.filter(Objects::nonNull)
.collect(Collectors.joining(" UNION "));
后者可以与前面的流操作合并,替换创建queriesMapKeys
的嵌套循环:
String sqlQuery = Arrays.stream(elementFilter)
.flatMap(element -> Arrays.stream(typeFilter)
.map(type -> queries.get(element + "_" + type + "_QUERY")))
.filter(Objects::nonNull)
.collect(Collectors.joining(" UNION "));