排序基于Java中的另一个集合

时间:2015-11-12 08:00:58

标签: java

让我们说我有两个名为desiredCompanies的集合作为数组,公司资源作为公司列表:

   List<String>  desiredCompanies  = Arrays.asList("AAA", "AAB", "AAC");

   List<Company>  companiesSource  = new ArrayList<Company>();

   Company item1= new Company();
   item1.setCode("AAB");
   item1.setPercent(200);
   item1.setLocation("America");
   companiesSource.add(item1);

   Company item2= new Company();
   item2.setCode("AAX");
   item2.setPercent(900);
   item2.setLocation("Africa");
   companiesSource.add(item2);

   Company item3= new Company();
   item3.setCode("AAC");
   item3.setPercent(900);
   item3.setLocation("Singapore");
   companiesSource.add(item3);

   Company item4= new Company();
   item4.setCode("AAA");
   item4.setPercent(900);
   item4.setLocation("Singapore");
   companiesSource.add(item4);

   Company item5= new Company();
   item5.setCode("AAR");
   item5.setPercent(900);
   item5.setLocation("Japan");
   companiesSource.add(item5);

我希望获得一个包含新公司列表的结果列表,或者按照所需公司的顺序对现有公司资源进行排序,该公司应该只包含所需公司列表中存在的项目。

5 个答案:

答案 0 :(得分:1)

如果您希望排序列表中包含所需公司中每个代码的元素,则以下代码将执行此操作。对于companiesSources

中不存在的代码,这将在sortedList中具有空值
List<Company> sortedList = new ArrayList<>();
Map<String, Company> map = new HashMap<>();
for(Company company : companiesSource){
    map.put(company.getCode(), company);
}
for(String desired : desiredCompanies){       
    sortedList.add(map.get(desired));
}

如果您希望避免来自null的不存在Company引用的已排序集合中的desiredCompanies值,请使用以下代码:

List<Company>  sortedList  = new ArrayList<Company>();
Map<String, Company> map = new HashMap<>();
for(Company company : companiesSource) {
   map.put(company.getCode(), company);
}
for(String desired : desiredCompanies) {
    if(map.get(desired) != null) {
        sortedList.add(map.get(desired));
    }
}

答案 1 :(得分:0)

如果您确定code始终是一个字符串,您可以使用indexOf来获取订单(但效率不是很高):

    final List<String> desiredCompanies = Arrays.asList( "AAA", "AAB", "AAC" );

    List<Company> companiesSource = new ArrayList<Company>();

    /* compute & remove unneeded values here */

    Collections.sort( companiesSource, new Comparator<Company>() {
        @Override
        public int compare( Company o1, Company o2 ) {
            int order1 = desiredCompanies.indexOf( o1.getCode() );
            int order2 = desiredCompanies.indexOf( o2.getCode() );
            return Integer.signum( order1 - order2 );
        }
    } );

为了提高效率,您可以预先计算订单到另一套。

答案 2 :(得分:0)

Java 8风格:

List<Company> sortedDesiredCompanies = companiesSource.stream()
    .filter(c -> desiredCompanies.contains(c.getCode())).sort()
    .collect(Collectors.toList());

答案 3 :(得分:0)

您可以根据代码位于companiesSource列表中筛选出公司。然后,您可以通过实现自己的Comparator根据该代码的索引对它们进行排序,然后将它们与Java 8的流API一起使用。

Comparator

public class DesirabilityComparator implements Comparator<Company> {
        private List<String> desiredCompanies;
        public DesirabilityComparator(List<String> desiredCompanies) {
            this.desiredCompanies = desiredCompanies;
        }

        @Override
        public int compare(Company c1, Company c2) {
            return Integer.compare(desiredCompanies.indexOf(c1.getCode()),
                                   desiredCompanies.indexOf(c2.getCode()));
        }
    }

全部放在一起:

List<Company> sortedAndFilteredCompanies =
        companiesSource.stream()
                       .filter(c -> desiredCompanies.contains(c.getCode()))
                       .sorted(new DesirabilityComparator(desiredCompanies))
                       .collect(Collectors.toList());

编辑:
正如aioobe评论的那样,使用Comparator.comparing

可以更优雅地完成这项工作
List<Company> sortedAndFilteredCompanies =
        companiesSource.stream()
                       .filter(c -> desiredCompanies.contains(c.getCode()))
                       .sorted(Comparator.comparing(c -> desiredCompanies.indexOf(c.getCode()))
                       .collect(Collectors.toList());

答案 4 :(得分:0)

虽然它可能不是高效代码,但我建议将代码分解为逻辑单元,例如:

public static void main(String[] args) {
    // register companies by their codes to look them up
    // alternativly, you can implement this in a ``Company(String code)`` constructor
    // along with a static accessible registry map in ``Company``
    Map<String, Company> companyRegistry = new HashMap<>();
    for(Company c : getCompanies()) {
        companyRegistry.put(c.getCode(), c);
    }

    // execute query on model and print out results
    System.out.println(queryCompanies(companyRegistry, "AAA", "AAB", "AAC"));
}

static List<Company> getCompanies() {
    // collect all companies you are going to use later
    List<Company> result = new ArrayList<>();
    Company c;

    // better add a constructor/factory method as shortcut
    // or load the objects from a database
    result.add(c = new Company());
    c.setCode("AAB");
    c.setPercent(200);
    c.setLocation("America");

    result.add(c = new Company());
    c.setCode("AAX");
    c.setPercent(900);
    c.setLocation("Africa");

    result.add(c = new Company());
    c.setCode("AAC");
    c.setPercent(900);
    c.setLocation("Singapore");

    result.add(c = new Company());
    c.setCode("AAA");
    c.setPercent(900);
    c.setLocation("Singapore");

    result.add(c = new Company());
    c.setCode("AAR");
    c.setPercent(900);
    c.setLocation("Japan");

    return result;
}

static List<Company> queryCompanies(Map<String, Company> companyRegistry, String... desiredCompanies) {
    // add "-ea" as VM-option to enable assertions
    // this is just a friendly check to avoid duplicates, you may remove it
    assert new HashSet<>(Arrays.asList(desiredCompanies)).size() == desiredCompanies.length : "desiredCompany contains duplicates";

    List<Company>  result  = new ArrayList<>((int)desiredCompanies.length);

    for(String desiredCompany : desiredCompanies) {
        Company desired = companyRegistry.get(desiredCompany);
        if(desired != null) {
            result.add(desired);
        }
    }
    return result;
}