给定一个字符串列表/数组:
document
document (1)
document (2)
document (3)
mypdf (1)
mypdf
myspreadsheet (1)
myspreadsheet
myspreadsheet (2)
如何删除所有重复项但仅保留最高副本号?
结束结果:
document (3)
mypdf (1)
myspreadsheet (2)
答案 0 :(得分:3)
你提出了一个广泛的问题,所以这里有一个非特定的(但仍然是)"完整的"回答:
换句话说:它只需要这么简单的收据来解决这个问题;现在只需要花时间将这些伪代码指令转换为实际代码。
对于记录:如果您的文件布局真的如上所示,那么事情会变得容易一些 - 因为您的数字似乎正在增加。我的意思是:
X (1)
X (2)
X (3)
比
更容易治疗X (1)
X (3)
X (2)
在你的情况下,假设最后 X(n)包含最大的n,似乎可以节省。这使得使用HashMap(由cainiaofei建议)是一个很好的解决方案。
答案 1 :(得分:1)
替代解决方案
使用HashMap
密钥是名称(例如文档文档的名称(1)
文件(2)文件(3)都是文件)
可以通过此代码
实现str.substring(0,str.indexOf('(')).trim()
并且值是密钥存在的时间,最后遍历地图获取对应值为max 的密钥,结果为key(value-1)
< / p>
答案 2 :(得分:0)
我建议你使用词典:
Map<String, Integer> dict = new HashMap<>();
for (String s : listOfInput){
String name = s.split(" ")[0];
String version = s.split(" ")[1].charAt(1);
if(dict.get(name)!=null){
if (Integer.parseInt(version) < dict.get(name)){
continue;
}
}
dict.put(name, version);
}
数据将在字典的末尾:
键|值
文件| 3
mypdf | 1
myspreadsheet | 2
答案 3 :(得分:0)
这是一种可能的方法,但只有在版本号不超过9 >时才会使用 :
1)按相反顺序对列表进行排序,以便最新版本首先出现
(*)排序基于字母顺序,除非您的版本号超过一位数,否则您应该非常精细。例如10,出现在9之前,按字母排序。
您的列表将变为:
myspreadsheet (2)
myspreadsheet (1)
myspreadsheet
mypdf (1)
mypdf
document (3)
document (2)
document (1)
document
2)迭代列表,只保留给定文档的第一次出现(即最近感谢反向排序)
3)如果您愿意,可以将剩余列表排序为更自然的顺序
List<String> documents = new ArrayList<String>();
documents.add("document");
documents.add("document (1)");
documents.add("document (2)");
documents.add("document (3)");
documents.add("mypdf (1)");
documents.add("mypdf");
documents.add("myspreadsheet (1)");
documents.add("myspreadsheet");
documents.add("myspreadsheet (2)");
// 1) Sort in reverse order, so that the most recent document version appears first
Collections.sort(documents, Collections.reverseOrder());
String lastDocumentName = "";
ListIterator<String> iter = documents.listIterator();
// 2)
while (iter.hasNext()) {
String document = iter.next();
// Store the first part of the String , i.e the document name (without version)
String firstPart = document.split("\\s+")[0];
// Check if this document is a version of the last checked document
// If it is the case, this version is anterior, remove it from the list
if (lastDocumentName.equals(firstPart)) {
iter.remove();
}
// Store this document's name as the last one checked
lastDocumentName = firstPart;
}
// 3) Sort back to natural order
Collections.sort(documents);
for (String doc : documents) {
System.out.println(doc);
}
答案 4 :(得分:0)
这是一个使用Map
的简单解决方案。首先,您遍历列表,拆分字符串,然后将其添加到地图中,并将名称作为键,以及作为值在paranthesis中的内容。并为每个条目检查密钥是否已存在。如果密钥存在,则比较该值,如果该值大于已存储的值,则将下一个条目添加到地图中。最后,您将遍历地图并获取列表。
这可能适用于任何类型的输入。我想......
当然,这可以比这更好。如果有人有任何建议,请随时分享。
public static void main(String[] args) {
List<String> list = Arrays.asList("document", "document (1)", "document (2)", "document (3)", "mypdf (1)", "mypdf", "myspreadsheet (1)",
"myspreadsheet", "myspreadsheet (2)");
Map<String, Integer> counterMap = new HashMap<>();
List<String> newList = new ArrayList<>();
for (String item : list) {
if (item.indexOf(')') != -1) {
String namePart = item.substring(0, item.indexOf('(')).trim();
Integer numberPart = Integer.parseInt(item.substring(item.indexOf('(') + 1, item.indexOf(')')));
Integer existingValue = counterMap.get(namePart);
if (existingValue != null) {
if (numberPart > existingValue) {
counterMap.put(namePart, numberPart);
}
} else {
counterMap.put(namePart, numberPart);
}
} else {
newList.add(item);
}
}
Iterator<Entry<String, Integer>> iterator = counterMap.entrySet().iterator();
while (iterator.hasNext()) {
Entry<String, Integer> next = iterator.next();
String key = next.getKey();
Integer value = next.getValue();
if (newList.contains(key)) {
newList.remove(key);
}
newList.add(key + " (" + value + ")");
}
System.out.println(newList);
}
答案 5 :(得分:0)
让我们利用Stream API对我们的文档进行分组,并通过按版本号对字符串进行排序来选择最新版本。请记住,那些静态方法实施得很差,因为你没有给我们太多关于命名策略的信息,但这个想法应该是明确的。
算法:
<强>解决方案:强>
Map<String, List<String>> grouped = input.stream()
.collect(Collectors.groupingBy(preprocessedString(), Collectors.toList()));
List<String> finalResult = grouped.entrySet().stream()
.map(e -> e.getValue().stream()
.max(Comparator.comparing(revisionNumber())).get()) //at this point we have at least one element
.collect(Collectors.toList());
}
帮助器解析函数:
private static Function<String, Integer> revisionNumber() {
return s -> s.contains("(") ? Integer.valueOf(s.substring(s.indexOf('(') + 1, s.indexOf(')'))) : 0;
}
private static Function<String, String> preprocessedString() {
return s -> s.contains("(") ? s.substring(0, s.lastIndexOf("(")).trim() : s.trim();
}
<强>输入:强>
List<String> input = Arrays.asList(
"document",
"document (1)",
"document (2)",
"document (3)",
"mypdf (1)",
"mypdf",
"myspreadsheet (12)",
"myspreadsheet",
"myspreadsheet (2)",
"single");
<强>结果强>:
[single, myspreadsheet (12), document (3), mypdf (1)]
答案 6 :(得分:0)
我们实际上不需要知道元素是否包含多个空格或其他内容。我们可以从最后开始,检查元素是否重复(看看是否有“)”。
通过document.getElementByID
进行一次整理就足以获得我们需要的所有信息。假设,我提供了一个解决方案,它将最高外观值保存为document.getElementById
中的 VALUE ,该地图将具有 KEYs 给定输入中的所有元素列表。
之后,您可以通过List
再次创建结果Map
。
List
答案 7 :(得分:-5)
Set<T> mySet = new HashSet<T>(Arrays.asList(Your));
我从stackoverflow的另一个用户发现,尝试它是否有效。祝你好运:)