有一个简单的类,如:
public class Label {
public String id;
public double amount;
}
拥有包含以下值的列表(列表按amount
升序排序):
id amount
----------------
1742 10
1742 11
1647 12
4217 13
1647 14
1742 15
是否有一种简单的方法来压缩列表,以便只保留id
的最低金额。因此,压缩后,列表应如下所示:
id amount
----------------
1742 10
1647 12
4217 13
答案 0 :(得分:1)
如果我理解正确,您想要从Label对象列表中删除双打。 有一些简单的方法,例如为列表创建自定义比较器:
文档:https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html Stack Overflow post:Collections sort(List<T>,Comparator<? super T>) method example
另一种方法是使用地图,因为据我所知,你可以使用两个值,因此使用类似TreeMap和自定义比较器^也可能是一个解决方案。 否则,您可以开发自己的排序算法,同时将对象与另一个对象进行比较,同时根据您的标准排序和跳过双打,例如Buble排序可以调整以做到这一点,大多数排序技术也是如此。
答案 1 :(得分:0)
许多方法都可以做到这一点。怎么样(完全未经测试,很可能不会编译):
public static List<Label> deduped(List<Label> yourSortedList) {
List<Label> output = new LinkedList<>();
assert yourSortedList.size() > 0;
Label lastVal = yourSortedList.get(0);
for (Label l : yourSortedList) {
if (!lastVal.id.equals(l.id)) {
output.add(lastVal);
lastVal = l;
}
}
output.add(lastVal);
return output;
}
如果上面没有至少一个错误,我会非常惊讶,但希望你能得到一般的想法。
答案 2 :(得分:0)
这是一种做法。方法makeUnique()将仅保留那些具有最小金额的标签。
<style>
body{
font-size : 20px;
}
</style>
答案 3 :(得分:0)
几乎每个人都是正确的,但谈到简单的方式
只需使用java.util.Set
并覆盖Label类的equals()
和hashCode()
方法。
除此之外还有很多方法。
执行此操作的方法之一
List<Label> originalList = new ArrayList<Label>();
// above conatins your original List
List<Label> result = new ArrayList<Label>();
Set<String> label = new HashSet<String>();
for( Label item : originalList ) {
if( label.add( item.getId() ) {
result.add( item );
}
}
您需要在班级中使用getId()
的Getter方法
答案 4 :(得分:0)
由于列表已经在金额上排序,您只需要在列表第一次出现时将对象标签包括在内。如果使用字典存储已输入元素的 id ,则可以生成包含确切元素的新列表。像这样:
public static List<Label> compact(List<Label> l)
{
Set<String> ids = new HashSet<>();
List<Label> toret = new ArrayList<>();
for(Label label: l) {
if ( !ids.contains( label.id ) ) {
ids.add( label.id );
toret.add( label );
}
}
return toret;
}
由于我们使用列表,因此Antoher的可能性是使用相同的列表进行压缩&#34;就位#34;考虑到这种可能性使用较少的内存,但速度较慢(因为它必须在循环中每次查找元素&#39; i,这在LinkedList中可能很昂贵)。
public static void compactInPlace(List<Label> l)
{
Set<String> ids = new HashSet<>();
for(int i = 0; i < l.size(); ++i) {
if ( !ids.contains( l.get( i ).id ) ) {
ids.add( l.get( i ).id );
} else {
l.remove( i );
--i;
}
}
return;
}
在此处找到代码:http://ideone.com/B4Gggt
希望这有帮助。
答案 5 :(得分:0)
使用Java 8 Streams,你可以这样做:
import java.util.Optional;
import java.util.List;
import java.util.Map.Entry;
import java.util.stream.Collectors;
public static List<Label> getDistinctMinLabels(List<Label> labels) {
return labels
.stream()
.collect(
// group by label id
// and of each group get the label with the minimum amount
Collectors.groupingBy(
label -> label.id,
Collectors.minBy((l1, l2) -> Double.compare(l1.amount, l2.amount))
)
)
.entrySet()
.stream()
.map(Entry::getValue)
.map(optional -> optional.get()) // Collectors.minBy returns an Optional<Label>
.collect(Collectors.toList());
}
此功能效率最高,但在标签未排序时也有效。