在Java中,如何根据一个列表对另一个列表进行排序?

在Java中,如何根据一个列表对另一个列表进行排序?,java,list,sorting,arraylist,Java,List,Sorting,Arraylist,我见过其他几个类似于这个问题的问题,但我还没有找到任何解决我问题的方法 我的用例是这样的:用户最初有一个项目列表(listA)。他们对项目进行重新排序,并希望保持该顺序(listB),但是,由于限制,我无法在后端保持该顺序,因此我必须在检索listA后对其进行排序 基本上,我有两个ArrayList(listA和listB)。一个具有列表的特定顺序(listB),另一个具有项目列表(listA)。我想根据listB对listA进行排序。如果对象引用应该相同,可以初始化listA new list

我见过其他几个类似于这个问题的问题,但我还没有找到任何解决我问题的方法

我的用例是这样的:用户最初有一个项目列表(listA)。他们对项目进行重新排序,并希望保持该顺序(listB),但是,由于限制,我无法在后端保持该顺序,因此我必须在检索listA后对其进行排序


基本上,我有两个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)..