两个list列表排序的问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两个list列表排序的问题相关的知识,希望对你有一定的参考价值。
现在有两个list列表
List<Product> listA=new ArrayList() ;
List<Product> listB=new ArrayList();
Product类中都有个字段是时间类型
现在的问题通过什么方法按照product类中时间字段排序 然后把两个列表合并为一个列表listC
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
public class SortBean
public static void main(String[] args) throws InterruptedException
// TODO Auto-generated method stub
List<Product> l1=new ArrayList() ;
List<Product> l2=new ArrayList();
List<Product> l3=new ArrayList();
for(int i=0;i<5;i++)
Product p=new Product(String.valueOf(i),new Date());
System.out.println(p);
l1.add(p);
Thread.sleep(1000);
for(int i=0;i<5;i++)
Product p=new Product(String.valueOf(i),new Date());
System.out.println(p);
l2.add(p);
Thread.sleep(1000);
l3.addAll(l2);
l3.addAll(l1);
System.out.println("原list--------------------------------");
for(Product l:l3)
System.out.println(l.getId()+"||"+l.getDate());
System.out.println("排序后的list--------------------------------");
Collections.sort(l3);
for(Product l:l3)
System.out.println(l.getId()+"--"+l.getDate());
package sort;
import java.util.Date;
public class Product implements Comparable<Product>
private String id;
private Date date;
public String getId()
return id;
public void setId(String id)
this.id = id;
public Date getDate()
return date;
public void setDate(Date date)
this.date = date;
public Product(String id, Date date)
super();
this.id = id;
this.date = date;
@Override
public String toString()
return "Product [date=" + date + ", id=" + id + "]";
@Override
public int compareTo(Product o)
// TODO Auto-generated method stub
return this.date.compareTo(o.date);
product类实现比较方法就行
然后用collections.sort 参考技术C java.util.Collections
static <T> void sort(List<T> list, Comparator<? super T> c)
Sorts the specified list according to the order induced by the specified
List<Product> list=......;
list=java.util.Collections.sort(list, new Comparator<Product>()
public int compare(Product o1, Product o2)
return o1.getDate().compareTo(o2.getDate());
);追问
前辈 能否白话一点
本回答被提问者和网友采纳从另一个列表 ID 对列表进行排序
【中文标题】从另一个列表 ID 对列表进行排序【英文标题】:Sort a list from another list IDs 【发布时间】:2013-02-22 21:24:40 【问题描述】:我有一个这样的标识符列表:
List<long> docIds = new List<long>() 6, 1, 4, 7, 2 ;
Morover,我有另一个<T>
项目列表,它们由上述 id 表示。
List<T> docs = GetDocsFromDb(...)
我需要在两个集合中保持相同的顺序,以便List<T>
中的项目必须与第一个中的项目位于相同的位置(由于搜索引擎评分的原因)。而这个过程不能在GetDocsFromDb()
函数中完成。
如有必要,可以将第二个列表更改为其他结构(例如Dictionary<long, T>
),但我不想更改它。
是否有任何简单有效的方法可以使用 LINQ 执行此“取决于某些 ID 的排序”?
【问题讨论】:
您确定每个docId
在docs
中只出现一次,什么属性将保存Id
或需要选择器Func<T, long>
?
第一个列表是否代表“主列表”?换句话说,第二个列表是代表第一个列表的一部分(或全部)的子集吗?
【参考方案1】:
docs = docs.OrderBy(d => docsIds.IndexOf(d.Id)).ToList();
【讨论】:
@BorjaLópez,一个简短的说明。您在问题中提到了效率。IndexOf
对于您的示例来说是完全可以接受的,而且非常简单。如果您有很多数据,我的答案可能更适合。 ***.com/questions/3663014/…
@DenysDenysenko 太棒了。非常感谢;正是我想要的。
如果文档中的元素在排序列表中没有 id,则不起作用
相当低效 - IndexOf 正在为源集合中的每个元素调用,而 OrderBy 必须对元素进行排序。 @Jodrell 的解决方案要快得多。
@DanHunex 如果您需要不存在的 id 出现在列表的末尾,您可以这样做: .OrderBy(d=> var index = docIds.IndexOf(d.Id); if ( index == -1) index = docIds.Count; 返回索引; )【参考方案2】:
一种简单的方法是按顺序压缩:
List<T> docs = GetDocsFromDb(...).Zip(docIds, Tuple.Create)
.OrderBy(x => x.Item2).Select(x => x.Item1).ToList();
【讨论】:
因为Zip
将每个索引(成一个元组)与相应列表中相同位置的文档组合在一起。然后 OrderBy 按索引部分对元组进行排序,然后 select 从现在排序的列表中挖掘我们的文档。
但是,GetDocsFromDb 的结果是无序的,因此您将创建 Item1
与 Item2
无关的元组。
我认为这会产生不正确的结果,因为订购执行 uppon id 而不是索引。【参考方案3】:
由于您没有指定T
,
IEnumerable<T> OrderBySequence<T, TId>(
this IEnumerable<T> source,
IEnumerable<TId> order,
Func<T, TId> idSelector)
var lookup = source.ToDictionary(idSelector, t => t);
foreach (var id in order)
yield return lookup[id];
是你想要的通用扩展。
也许你可以使用这样的扩展,
var orderDocs = docs.OrderBySequence(docIds, doc => doc.Id);
一个更安全的版本可能是
IEnumerable<T> OrderBySequence<T, TId>(
this IEnumerable<T> source,
IEnumerable<TId> order,
Func<T, TId> idSelector)
var lookup = source.ToLookup(idSelector, t => t);
foreach (var id in order)
foreach (var t in lookup[id])
yield return t;
如果source
与order
不完全压缩,这将起作用。
【讨论】:
我使用了这个解决方案,它奏效了。就是这样,我必须使方法静态和类静态。【参考方案4】:Jodrell 的答案是最好的,但实际上他重新实现了System.Linq.Enumerable.Join
。 Join 也使用 Lookup 并保持源的排序。
docIds.Join(
docs,
i => i,
d => d.Id,
(i, d) => d);
【讨论】:
这就是我们正在寻找的答案 这只是证明Join太难理解了,因为大家一致认为重写更容易。以上是关于两个list列表排序的问题的主要内容,如果未能解决你的问题,请参考以下文章