在Java中,如何根据一个列表对另一个列表进行排序?
我见过其他几个类似于这个问题的问题,但我还没有找到任何解决我问题的方法 我的用例是这样的:用户最初有一个项目列表(listA)。他们对项目进行重新排序,并希望保持该顺序(listB),但是,由于限制,我无法在后端保持该顺序,因此我必须在检索listA后对其进行排序在Java中,如何根据一个列表对另一个列表进行排序?,java,list,sorting,arraylist,Java,List,Sorting,Arraylist,我见过其他几个类似于这个问题的问题,但我还没有找到任何解决我问题的方法 我的用例是这样的:用户最初有一个项目列表(listA)。他们对项目进行重新排序,并希望保持该顺序(listB),但是,由于限制,我无法在后端保持该顺序,因此我必须在检索listA后对其进行排序 基本上,我有两个ArrayList(listA和listB)。一个具有列表的特定顺序(listB),另一个具有项目列表(listA)。我想根据listB对listA进行排序。如果对象引用应该相同,可以初始化listA new list
基本上,我有两个ArrayList(listA和listB)。一个具有列表的特定顺序(listB),另一个具有项目列表(listA)。我想根据listB对listA进行排序。如果对象引用应该相同,可以初始化listA new
listA = new ArrayList(listB)
一种方法是在listB中循环,并在listA包含项目时将其添加到临时列表中:
List<?> tempList = new ArrayList<?>();
for(Object o : listB) {
if(listA.contains(o)) {
tempList.add(o);
}
}
listA.removeAll(listB);
tempList.addAll(listA);
return tempList;
List templast=new ArrayList();
for(对象o:listB){
if(列表a.contains(o)){
圣殿骑士。添加(o);
}
}
listA.removeAll(listB);
圣殿骑士阿达尔(利斯塔);
返回圣殿骑士;
正如Tim Herold所写,如果对象引用应该相同,您可以将listB复制到listA,或者:
listA = new ArrayList(listB);
或者,如果您不想更改listA引用的列表,请执行以下操作:
listA.clear();
listA.addAll(listB);
如果引用不同,但listA和listB中的对象之间存在某种等价关系,则可以使用自定义的比较器对listA进行排序,该比较器在listB中查找对象,并将其在listB中的索引用作排序键。蛮力搜索listB的天真实现在性能上不是最好的,但在功能上是足够的。Collections.sort(listB,new Comparator()){
Collections.sort(listB, new Comparator<Item>() {
public int compare(Item left, Item right) {
return Integer.compare(listA.indexOf(left), listA.indexOf(right));
}
});
公共整数比较(项目左、项目右){
返回Integer.compare(listA.indexOf(左),listA.indexOf(右));
}
});
但是,这是非常低效的,您可能应该从listA创建一个映射
,以便更快地查找项目的位置
番石榴有一个现成的比较器来做这件事:不完全清楚你想要什么,但如果是这种情况:
A:[c,b,A]
B:[2,1,0]
您希望同时加载它们,然后生成:
C:[a,b,C]
那也许是这个
List c = new ArrayList(b.size());
for(int i=0;i<b.size();i++) {
c.set(b.get(i),a.get(i));
}
listc=newarraylist(b.size());
对于(int i=0;i假设您有一个listB
列表,它定义了您要排序的顺序listA
。这只是一个示例,但它演示了由列表定义的顺序,而不是数据类型的自然顺序:
List<String> listB = Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday");
然后,您可以创建自定义的比较器
,该比较器使用映射
创建订单:
public class ItemWeekdayComparator implements Comparator<Item>
{
private Map<String, Integer> sortOrder;
public ItemWeekdayComparator(Map<String, Integer> sortOrder)
{
this.sortOrder = sortOrder;
}
@Override
public int compare(Item i1, Item i2)
{
Integer weekdayPos1 = sortOrder.get(i1.getWeekday());
if (weekdayPos1 == null)
{
throw new IllegalArgumentException("Bad weekday encountered: " +
i1.getWeekday());
}
Integer weekdayPos2 = sortOrder.get(i2.getWeekday());
if (weekdayPos2 == null)
{
throw new IllegalArgumentException("Bad weekday encountered: " +
i2.getWeekday());
}
return weekdayPos1.compareTo(weekdayPos2);
}
}
根据您的设置,另一种可能有效的解决方案不是在listB中存储实例,而是从listA中存储索引。这可以通过将listA包装到自定义排序列表中来实现,如下所示:
public static class SortedDependingList<E> extends AbstractList<E> implements List<E>{
private final List<E> dependingList;
private final List<Integer> indices;
public SortedDependingList(List<E> dependingList) {
super();
this.dependingList = dependingList;
indices = new ArrayList<>();
}
@Override
public boolean add(E e) {
int index = dependingList.indexOf(e);
if (index != -1) {
return addSorted(index);
}
return false;
}
/**
* Adds to this list the element of the depending list at the given
* original index.
* @param index The index of the element to add.
*
*/
public boolean addByIndex(int index){
if (index < 0 || index >= this.dependingList.size()) {
throw new IllegalArgumentException();
}
return addSorted(index);
}
/**
* Returns true if this list contains the element at the
* index of the depending list.
*/
public boolean containsIndex(int index){
int i = Collections.binarySearch(indices, index);
return i >= 0;
}
private boolean addSorted(int index){
int insertIndex = Collections.binarySearch(indices, index);
if (insertIndex < 0){
insertIndex = -insertIndex-1;
this.indices.add(insertIndex, index);
return true;
}
return false;
}
@Override
public E get(int index) {
return dependingList.get(indices.get(index));
}
@Override
public int size() {
return indices.size();
}
}
公共静态类SortedPendingList扩展了AbstractList实现列表{
私人最终清单依赖清单;
私人最终名单索引;
公共分类待处理列表(列表依赖列表){
超级();
this.dependingList=dependingList;
索引=新的ArrayList();
}
@凌驾
公共布尔加法(E){
int index=dependingList.indexOf(e);
如果(索引!=-1){
返回addSorted(索引);
}
返回false;
}
/**
*在给定的位置将依赖列表的元素添加到此列表中
*原始索引。
*@param index要添加的元素的索引。
*
*/
公共布尔addByIndex(整数索引){
如果(索引<0 | |索引>=this.dependingList.size()){
抛出新的IllegalArgumentException();
}
返回addSorted(索引);
}
/**
*如果此列表包含当前位置的元素,则返回true
*依赖列表的索引。
*/
公共布尔containsIndex(int索引){
inti=Collections.binarySearch(索引,索引);
返回i>=0;
}
私有布尔addSorted(int索引){
int insertIndex=Collections.binarySearch(索引,索引);
如果(插入索引<0){
insertIndex=-insertIndex-1;
this.index.add(insertIndex,index);
返回true;
}
返回false;
}
@凌驾
公共E-get(int索引){
返回dependingList.get(index.get(index));
}
@凌驾
公共整数大小(){
返回索引。size();
}
}
然后,您可以按如下方式使用此自定义列表:
public static void main(String[] args) {
class SomeClass{
int index;
public SomeClass(int index) {
super();
this.index = index;
}
@Override
public String toString() {
return ""+index;
}
}
List<SomeClass> listA = new ArrayList<>();
for (int i = 0; i < 100; i++) {
listA.add(new SomeClass(i));
}
SortedDependingList<SomeClass> listB = new SortedDependingList<>(listA);
Random rand = new Random();
// add elements by index:
for (int i = 0; i < 5; i++) {
int index = rand.nextInt(listA.size());
listB.addByIndex(index);
}
System.out.println(listB);
// add elements by identity:
for (int i = 0; i < 5; i++) {
int index = rand.nextInt(listA.size());
SomeClass o = listA.get(index);
listB.add(o);
}
System.out.println(listB);
}
publicstaticvoidmain(字符串[]args){
上课{
整数指数;
公共类(int索引){
超级();
这个指数=指数;
}
@凌驾
公共字符串toString(){
返回“”+索引;
}
}
List listA=new ArrayList();
对于(int i=0;i<100;i++){
添加(新的SomeClass(i));
}
SortedPendingList listB=新的SortedPendingList(listA);
Random rand=新的Random();
//按索引添加元素:
对于(int i=0;i<5;i++){
int index=rand.nextInt(listA.size());
列表b.addByIndex(索引);
}
系统输出打印项次(列表B);
//按标识添加元素:
对于(int i=0;i<5;i++){
int index=rand.nextInt(listA.size());
SomeClass o=listA.get(索引);
清单b.添加(o);
}
系统输出打印项次(列表B);
}
当然,只有在原始列表中的元素不变的情况下,此自定义列表才有效。如果可能发生更改,您需要以某种方式侦听原始列表的更改,并更新自定义列表中的索引
另外请注意,SortedPendingList当前不允许再次添加listA中的元素——在这方面,它实际上与listA中的一组元素类似,因为这通常是您在此类设置中所需要的
向SortedPendingList添加内容的首选方法是已经知道元素的索引并通过
Collections.sort(listA, new ItemWeekdayComparator(weekdayOrder));
public static class SortedDependingList<E> extends AbstractList<E> implements List<E>{
private final List<E> dependingList;
private final List<Integer> indices;
public SortedDependingList(List<E> dependingList) {
super();
this.dependingList = dependingList;
indices = new ArrayList<>();
}
@Override
public boolean add(E e) {
int index = dependingList.indexOf(e);
if (index != -1) {
return addSorted(index);
}
return false;
}
/**
* Adds to this list the element of the depending list at the given
* original index.
* @param index The index of the element to add.
*
*/
public boolean addByIndex(int index){
if (index < 0 || index >= this.dependingList.size()) {
throw new IllegalArgumentException();
}
return addSorted(index);
}
/**
* Returns true if this list contains the element at the
* index of the depending list.
*/
public boolean containsIndex(int index){
int i = Collections.binarySearch(indices, index);
return i >= 0;
}
private boolean addSorted(int index){
int insertIndex = Collections.binarySearch(indices, index);
if (insertIndex < 0){
insertIndex = -insertIndex-1;
this.indices.add(insertIndex, index);
return true;
}
return false;
}
@Override
public E get(int index) {
return dependingList.get(indices.get(index));
}
@Override
public int size() {
return indices.size();
}
}
public static void main(String[] args) {
class SomeClass{
int index;
public SomeClass(int index) {
super();
this.index = index;
}
@Override
public String toString() {
return ""+index;
}
}
List<SomeClass> listA = new ArrayList<>();
for (int i = 0; i < 100; i++) {
listA.add(new SomeClass(i));
}
SortedDependingList<SomeClass> listB = new SortedDependingList<>(listA);
Random rand = new Random();
// add elements by index:
for (int i = 0; i < 5; i++) {
int index = rand.nextInt(listA.size());
listB.addByIndex(index);
}
System.out.println(listB);
// add elements by identity:
for (int i = 0; i < 5; i++) {
int index = rand.nextInt(listA.size());
SomeClass o = listA.get(index);
listB.add(o);
}
System.out.println(listB);
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class example {
public static void main(String[] args) {
List<Integer> ints = new ArrayList<Integer>();
ints.add(4);
ints.add(3);
ints.add(7);
ints.add(5);
Collections.sort(ints);
System.out.println(ints);
}
}
Object[] orderedArray = new Object[listA.size()];
for(int index = 0; index < listB.size(); index ++){
int position = listB.get(index); //this may have to be cast as an int
orderedArray[position] = listA.get(index);
}
//if you receive UnsupportedOperationException when running listA.clear()
//you should replace the line with listA = new List<Object>()
//using your actual implementation of the List interface
listA.clear();
listA.addAll(orderedArray);
public class HeavyPair<L extends Comparable<L>, R> implements Comparable<HeavyPair<L, ?>> {
public final L left;
public final R right;
public HeavyPair(L left, R right) {
this.left = left;
this.right = right;
}
public compareTo(HeavyPair<L, ?> o) {
return this.left.compareTo(o.left);
}
public static <L extends Comparable<L>, R> List<R> sort(List<L> weights, List<R> toSort) {
assert(weights.size() == toSort.size());
List<R> output = new ArrayList<>(toSort.size());
List<HeavyPair<L, R>> workHorse = new ArrayList<>(toSort.size());
for(int i = 0; i < toSort.size(); i++) {
workHorse.add(new HeavyPair(weights.get(i), toSort.get(i)))
}
Collections.sort(workHorse);
for(int i = 0; i < workHorse.size(); i++) {
output.add(workHorse.get(i).right);
}
return output;
}
}
ArrayList<String> listA = new ArrayList<String>();
ArrayList<String> listB = new ArrayList<String>();
int j = 0;
// list of returns of the compare method which will be used to manipulate
// the another comparator according to the sorting of previous listA
ArrayList<Integer> sortingMethodReturns = new ArrayList<Integer>();
public void addItemstoLists() {
listA.add("Value of Z");
listA.add("Value of C");
listA.add("Value of F");
listA.add("Value of A");
listA.add("Value of Y");
listB.add("this is the value of Z");
listB.add("this is the value off C");
listB.add("this is the value off F");
listB.add("this is the value off A");
listB.add("this is the value off Y");
Collections.sort(listA, new Comparator<String>() {
@Override
public int compare(String lhs, String rhs) {
// TODO Auto-generated method stub
int returning = lhs.compareTo(rhs);
sortingMethodReturns.add(returning);
return returning;
}
});
// now sort the list B according to the changes made with the order of
// items in listA
Collections.sort(listB, new Comparator<String>() {
@Override
public int compare(String lhs, String rhs) {
// TODO Auto-generated method stub
// comparator method will sort the second list also according to
// the changes made with list a
int returning = sortingMethodReturns.get(j);
j++;
return returning;
}
});
}
Collections.sort(listToSort,
Comparator.comparing(item -> listWithOrder.indexOf(item)));
listToSort.sort(Comparator.comparingInt(listWithOrder::indexOf));
/**
* Sorts list objectsToOrder based on the order of orderedObjects.
*
* Make sure these objects have good equals() and hashCode() methods or
* that they reference the same objects.
*/
public static void sortList(List<?> objectsToOrder, List<?> orderedObjects) {
HashMap<Object, Integer> indexMap = new HashMap<>();
int index = 0;
for (Object object : orderedObjects) {
indexMap.put(object, index);
index++;
}
Collections.sort(objectsToOrder, new Comparator<Object>() {
public int compare(Object left, Object right) {
Integer leftIndex = indexMap.get(left);
Integer rightIndex = indexMap.get(right);
if (leftIndex == null) {
return -1;
}
if (rightIndex == null) {
return 1;
}
return Integer.compare(leftIndex, rightIndex);
}
});
}
listB.sort((left, right) -> Integer.compare(list.indexOf(left), list.indexOf(right)));
listB.sort(Comparator.comparingInt(item -> list.indexOf(item)));
<K, T> List<T> sortByOrder(List<K> orderedKeys, List<T> objectsToOrder, Function<T, K> keyExtractor) {
AtomicInteger ind = new AtomicInteger(0);
Map<K, Integer> keyToIndex = orderedKeys.stream().collect(Collectors.toMap(k -> k, k -> ind.getAndIncrement(), (oldK, newK) -> oldK));
SortedMap<Integer, T> indexToObj = new TreeMap<>();
objectsToOrder.forEach(obj -> indexToObj.put(keyToIndex.get(keyExtractor.apply(obj)), obj));
return new ArrayList<>(indexToObj.values());
}
Map<Item, Integer> index = IntStream.range(0, listB.size()).boxed()
.collect(Collectors.toMap(listB::get, x -> x));
listA.sort((e1, e2) -> Integer.compare(index.get(c1), index.get(c2));
import java.util.Comparator;
import java.util.List;
public class ListComparator implements Comparator<String> {
private final List<String> orderedList;
private boolean appendFirst;
public ListComparator(List<String> orderedList, boolean appendFirst) {
this.orderedList = orderedList;
this.appendFirst = appendFirst;
}
@Override
public int compare(String o1, String o2) {
if (orderedList.contains(o1) && orderedList.contains(o2))
return orderedList.indexOf(o1) - orderedList.indexOf(o2);
else if (orderedList.contains(o1))
return (appendFirst) ? 1 : -1;
else if (orderedList.contains(o2))
return (appendFirst) ? -1 : 1;
return 0;
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<Employee> listToSort = new ArrayList<>();
listToSort.add(new Employee("a", "age11"));
listToSort.add(new Employee("c", "age33"));
listToSort.add(new Employee("b", "age22"));
listToSort.add(new Employee("a", "age111"));
listToSort.add(new Employee("c", "age3"));
listToSort.add(new Employee("b", "age2"));
listToSort.add(new Employee("a", "age1"));
List<String> listWithOrder = new ArrayList<>();
listWithOrder.add("a");
listWithOrder.add("b");
listWithOrder.add("c");
Collections.sort(listToSort, Comparator.comparing(item ->
listWithOrder.indexOf(item.getName())));
System.out.println(listToSort);
}
}
class Employee {
String name;
String age;
public Employee(String name, String age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public String getAge() {
return age;
}
@Override
public String toString() {
return "[name=" + name + ", age=" + age + "]";
}
}
Set<T> validItems = new HashSet<>(listB);
listA.clear();
listB.forEach(item -> {
if(validItems.contains(item)) {
listA.add(item);
}
});
fun <T> List<T>.sort(orderedList: List<T>): List<T> {
return if (size == orderedList.size) {
orderedList
} else {
var keepIndexCount = 0
mapIndexed { index, item ->
if (orderedList.contains(item)) {
orderedList[index - keepIndexCount]
} else {
keepIndexCount++
item
}
}
}}
List<String> listA;
Comparator<B> comparator = Comparator.comparing(e -> listA.indexOf(e.getValue()));
//call your comparator inside your list to be sorted
listB.stream().sorted(comparator)..