Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对java集合进行排序和分组_Java - Fatal编程技术网

对java集合进行排序和分组

对java集合进行排序和分组,java,Java,我有一个有名字和分数的物体。我想对这些对象的集合进行排序,以便它们按名称分组,并按每组中的最大分数排序(在组内也按分数递减排序) 让我展示一下我打算实现的目标。假设我有这些对象(名称、分数): (a,3) (a,9) (b,7) (b,10) (c,8) (c,3) 然后我希望它们按如下方式分类: (b,10) (b,7) (a,9) (a,3) (c,8) (c,3) 使用比较器是否可行?我想不出来,所以任何提示都将不胜感激。是的 在比较中首先优先选择名称,然后评分。它也将与排序的分数一起分组

我有一个有名字和分数的物体。我想对这些对象的集合进行排序,以便它们按名称分组,并按每组中的最大分数排序(在组内也按分数递减排序)

让我展示一下我打算实现的目标。假设我有这些对象(名称、分数):

(a,3)
(a,9)
(b,7)
(b,10)
(c,8)
(c,3)

然后我希望它们按如下方式分类:

(b,10)
(b,7)
(a,9)
(a,3)
(c,8)
(c,3)

使用比较器是否可行?我想不出来,所以任何提示都将不胜感激。

是的

在比较中首先优先选择
名称
,然后评分。它也将与排序的分数一起分组

    List<Score> scores = new ArrayList<Score>();
    scores.add(new Score("a", 58));
    scores.add(new Score("a", 10));
    scores.add(new Score("b", 165));
    scores.add(new Score("a", 1));
    scores.add(new Score("b", 1658));
    scores.add(new Score("c", 1));
    scores.add(new Score("c", 10));
    scores.add(new Score("c", 0));

    Collections.sort(scores, new Comparator<Score>() {

        public int compare(Score o1, Score o2) {
            if (o1.getName().compareTo(o2.getName()) == 0) {
                return o2.getScore() - o1.getScore();
            } else {
                return o1.getName().compareTo(o2.getName());
            }
        }
    });
    System.out.println(scores);
List scores=new ArrayList();
分数。添加(新分数(“a”,58));
分数。添加(新分数(“a”,10));
分数。添加(新分数(“b”,165));
分数。添加(新分数(“a”,1));
分数。添加(新分数(“b”,1658));
分数。添加(新分数(“c”,1));
分数。添加(新分数(“c”,10));
分数。添加(新分数(“c”,0));
Collections.sort(分数,新比较器(){
公共整数比较(分数o1,分数o2){
如果(o1.getName().compareTo(o2.getName())==0){
返回o2.getScore()-o1.getScore();
}否则{
返回o1.getName().compareTo(o2.getName());
}
}
});
系统输出打印项次(分数);
更新 正如克里斯指出的那样

import java.util.*;

/**
 *
 * @author Jigar
 */
class Score {

    private String name;
    private List<Integer> scores;

    public Score() {
    }

    public Score(String name, List<Integer> scores) {
        this.name = name;
        this.scores = scores;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Integer> getScores() {
        return scores;
    }

    public void setScores(List<Integer> scores) {
        this.scores = scores;
    }

    @Override
    public String toString() {
        return name + " , " + scores + "\n";
    }
}

public class ScoreDemo { 

    public static void main(String[] args) {
        List<Score> scores = new ArrayList<Score>();


        List<Integer> lstA = new ArrayList<Integer>();
        lstA.add(3);
        lstA.add(9);
        lstA.add(7);
        Collections.sort(lstA);
        Collections.reverse(lstA);

        List<Integer> lstB = new ArrayList<Integer>();
        lstB.add(10);
        lstB.add(8);
        lstB.add(3);
        Collections.sort(lstB);
        Collections.reverse(lstB);

        List<Integer> lstC = new ArrayList<Integer>();
        lstC.add(8);
        lstC.add(3);
        Collections.sort(lstC);
        Collections.reverse(lstC);


        scores.add(new Score("a", lstA));
        scores.add(new Score("b", lstB));
        scores.add(new Score("c", lstC));





        Collections.sort(scores, new Comparator<Score>() {

            public int compare(Score o1, Score o2) {
                return o2.getScores().get(0).compareTo(o1.getScores().get(0));
            }
        });
        System.out.println(scores);

    }
}
import java.util.*;
/**
*
*@作者Jigar
*/
班级成绩{
私有字符串名称;
私人名单分数;
公众分数(){
}
公共分数(字符串名称、列表分数){
this.name=名称;
这个分数=分数;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共列表getScores(){
返回分数;
}
公开考试分数(列出分数){
这个分数=分数;
}
@凌驾
公共字符串toString(){
返回名称+“,“+分数+”\n”;
}
}
公共类{
公共静态void main(字符串[]args){
列表分数=新的ArrayList();
List lstA=new ArrayList();
lstA.添加(3);
lstA.添加(9);
lstA.添加(7);
集合排序(lstA);
收藏。反向(lstA);
List lstB=new ArrayList();
lstB.添加(10);
lstB.添加(8);
lstB.添加(3);
集合。排序(lstB);
收藏。反向(lstB);
List lstC=new ArrayList();
lstC.添加(8);
lstC.添加(3);
集合。排序(lstC);
收藏。反向(lstC);
分数。添加(新分数(“a”,lstA));
分数。添加(新分数(“b”,lstB));
分数。添加(新分数(“c”,lstC));
Collections.sort(分数,新比较器(){
公共整数比较(分数o1,分数o2){
返回o2.getScores().get(0).compareTo(o1.getScores().get(0));
}
});
系统输出打印项次(分数);
}
}

不,不能用一个
比较器进行单一排序

你必须:

  • 按名称分组
  • 按组中的最高分数对组进行排序
  • 然后,您需要将组展平回到列表中
  • 使用Java8 编辑:自从我写了这个答案后,Java 8就问世了,这大大简化了问题:

    import java.util.*;
    import static java.util.Comparator.*;
    import static java.util.stream.Collectors.*;
    

    其中,记录被分组为排序的
    TreeSet
    s,而不是作为流的第一个操作对值进行排序,然后按其第一个最高值对集合进行排序

    如果组较大,则在排序之前进行分组是合适的,以减少冗余比较


    实施可比的
    : 通过让您的记录实现
    可比性

    public class Record implements Comparable<Record> {
        @Override
        public int compareTo(Record other) {
            // Highest first
            return -Integer.compare(getScore(), other.getScore());
    
            /* Or equivalently:
               return Integer.compare(other.getScore(), getScore());
            */
        }
        ...
    }
    
    公共类记录实现可比较{
    @凌驾
    公共整数比较(记录其他){
    //最高优先
    return-Integer.compare(getScore(),other.getScore());
    /*或相当于:
    返回整数.compare(other.getScore(),getScore());
    */
    }
    ...
    }
    

    List result=records.stream()
    .collect(groupingBy(记录::getName,toCollection(树集::新建)))
    .values().stream()
    .sorted(比较(SortedSet::first))
    .flatMap(集合::流)
    .collect(toList());
    

    Java 8之前 编辑:这里是一个非常粗略的单元测试,演示了一种方法。我还没有把它清理干净

    像这样的东西在Java中是痛苦的,我通常会使用它

    import org.junit.Test;
    
    import java.util.*;
    
    import static java.util.Arrays.asList;
    import static org.junit.Assert.assertEquals;
    
    public class GroupSortTest {
    
        @Test
        public void testGroupSort() {
            List<Record> records = asList(
                    new Record("a", 3),
                    new Record("a", 9),
                    new Record("b", 7),
                    new Record("b", 10),
                    new Record("c", 8),
                    new Record("c", 3));
    
            List<SortedMap<Integer, Record>> recordsGroupedByName = groupRecordsByNameAndSortedByScoreDescending(records);
            Collections.sort(recordsGroupedByName, byHighestScoreInGroupDescending());
            List<Record> result = flattenGroups(recordsGroupedByName);
    
            List<Record> expected = asList(
                    new Record("b", 10),
                    new Record("b", 7),
                    new Record("a", 9),
                    new Record("a", 3),
                    new Record("c", 8),
                    new Record("c", 3));
    
            assertEquals(expected, result);
        }
    
        private List<Record> flattenGroups(List<SortedMap<Integer, Record>> recordGroups) {
            List<Record> result = new ArrayList<Record>();
            for (SortedMap<Integer, Record> group : recordGroups) {
                result.addAll(group.values());
            }
            return result;
        }
    
        private List<SortedMap<Integer, Record>> groupRecordsByNameAndSortedByScoreDescending(List<Record> records) {
            Map<String, SortedMap<Integer, Record>> groupsByName = new HashMap<String, SortedMap<Integer, Record>>();
            for (Record record : records) {
                SortedMap<Integer, Record> group = groupsByName.get(record.getName());
                if (null == group) {
                    group = new TreeMap<Integer, Record>(descending());
                    groupsByName.put(record.getName(), group);
                }
                group.put(record.getScore(), record);
            }
            return new ArrayList<SortedMap<Integer, Record>>(groupsByName.values());
        }
    
        private DescendingSortComparator descending() {
            return new DescendingSortComparator();
        }
    
        private ByFirstKeyDescending byHighestScoreInGroupDescending() {
            return new ByFirstKeyDescending();
        }
    
        private static class ByFirstKeyDescending implements Comparator<SortedMap<Integer, Record>> {
            public int compare(SortedMap<Integer, Record> o1, SortedMap<Integer, Record> o2) {
                return o2.firstKey().compareTo(o1.firstKey());
            }
        }
    
        private static class DescendingSortComparator implements Comparator<Comparable> {
            public int compare(Comparable o1, Comparable o2) {
                return o2.compareTo(o1);
            }
        }
    }
    
    import org.junit.Test;
    导入java.util.*;
    导入静态java.util.Arrays.asList;
    导入静态org.junit.Assert.assertEquals;
    公共类GroupSortTest{
    @试验
    公共void testGroupSort(){
    列表记录=asList(
    新纪录(a,3),,
    新纪录(a,9),,
    新纪录(b,7),,
    新纪录(b,10),,
    新纪录(c,8),,
    新纪录("c,3);;
    列表记录GroupedByName=GroupRecordsByName和SortedByCoreDescending(记录);
    排序(recordsGroupedByName,byHighestScoreInGroupDescending());
    列表结果=组(recordsGroupedByName);
    预期列表=asList(
    新纪录(b,10),,
    新纪录(b,7),,
    新纪录(a,9),,
    新纪录(a,3),,
    新纪录(c,8),,
    新纪录("c,3);;
    资产质量(预期、结果);
    }
    专用列表组(列表记录组){
    列表结果=新建ArrayList();
    用于(分类地图组:记录组){
    result.addAll(group.values());
    }
    返回r
    
    public class Record implements Comparable<Record> {
        @Override
        public int compareTo(Record other) {
            // Highest first
            return -Integer.compare(getScore(), other.getScore());
    
            /* Or equivalently:
               return Integer.compare(other.getScore(), getScore());
            */
        }
        ...
    }
    
    List<Record> result = records.stream()
        .collect(groupingBy(Record::getName, toCollection(TreeSet::new)))
        .values().stream()
        .sorted(comparing(SortedSet::first))
        .flatMap(Collection::stream)
        .collect(toList());
    
    import org.junit.Test;
    
    import java.util.*;
    
    import static java.util.Arrays.asList;
    import static org.junit.Assert.assertEquals;
    
    public class GroupSortTest {
    
        @Test
        public void testGroupSort() {
            List<Record> records = asList(
                    new Record("a", 3),
                    new Record("a", 9),
                    new Record("b", 7),
                    new Record("b", 10),
                    new Record("c", 8),
                    new Record("c", 3));
    
            List<SortedMap<Integer, Record>> recordsGroupedByName = groupRecordsByNameAndSortedByScoreDescending(records);
            Collections.sort(recordsGroupedByName, byHighestScoreInGroupDescending());
            List<Record> result = flattenGroups(recordsGroupedByName);
    
            List<Record> expected = asList(
                    new Record("b", 10),
                    new Record("b", 7),
                    new Record("a", 9),
                    new Record("a", 3),
                    new Record("c", 8),
                    new Record("c", 3));
    
            assertEquals(expected, result);
        }
    
        private List<Record> flattenGroups(List<SortedMap<Integer, Record>> recordGroups) {
            List<Record> result = new ArrayList<Record>();
            for (SortedMap<Integer, Record> group : recordGroups) {
                result.addAll(group.values());
            }
            return result;
        }
    
        private List<SortedMap<Integer, Record>> groupRecordsByNameAndSortedByScoreDescending(List<Record> records) {
            Map<String, SortedMap<Integer, Record>> groupsByName = new HashMap<String, SortedMap<Integer, Record>>();
            for (Record record : records) {
                SortedMap<Integer, Record> group = groupsByName.get(record.getName());
                if (null == group) {
                    group = new TreeMap<Integer, Record>(descending());
                    groupsByName.put(record.getName(), group);
                }
                group.put(record.getScore(), record);
            }
            return new ArrayList<SortedMap<Integer, Record>>(groupsByName.values());
        }
    
        private DescendingSortComparator descending() {
            return new DescendingSortComparator();
        }
    
        private ByFirstKeyDescending byHighestScoreInGroupDescending() {
            return new ByFirstKeyDescending();
        }
    
        private static class ByFirstKeyDescending implements Comparator<SortedMap<Integer, Record>> {
            public int compare(SortedMap<Integer, Record> o1, SortedMap<Integer, Record> o2) {
                return o2.firstKey().compareTo(o1.firstKey());
            }
        }
    
        private static class DescendingSortComparator implements Comparator<Comparable> {
            public int compare(Comparable o1, Comparable o2) {
                return o2.compareTo(o1);
            }
        }
    }
    
        class Item{
          String name;
          int score;
        }
    
       new Comparator<Item>(){
    
           @Override
           public int compare(Item o1, Item o2) {
                if (o1.name.equals(o2.name)) {
                    return o1.score > o2.score ? 1 : -1; // might have to flip this. I didn't test
                }else {
                    return o1.name.compareTo(o2.name);
                }
           }
        };
    
    public class SortThings {
    
        static class Thing {
            public final String name;
            public final int score;
            public Thing(String name, int score) {
                this.name = name;
                this.score = score;
            }
            @Override
            public String toString() {
                return "(" + name + ", " + score + ")";
            }
        }
    
        public static void main(String[] args) {
            Collection<Thing> things = Arrays.asList(
                new Thing("a", 3),
                new Thing("a", 9),
                new Thing("b", 7),
                new Thing("b", 10),
                new Thing("c", 8),
                new Thing("c", 3)
            );
    
            SortedSet<SortedSet<Thing>> sortedGroups = sortThings(things);
    
            System.out.println(sortedGroups);
        }
    
        private static SortedSet<SortedSet<Thing>> sortThings(Collection<Thing> things) {
            final Comparator<Thing> compareThings = new Comparator<Thing>() {
                public int compare(Thing a, Thing b) {
                    Integer aScore = a.score;
                    Integer bScore = b.score;
                    return aScore.compareTo(bScore);
                }
            };
    
            // first pass
            Map<String, SortedSet<Thing>> groups = new HashMap<String, SortedSet<Thing>>();
            for (Thing obj: things) {
                SortedSet<Thing> group = groups.get(obj.name);
                if (group == null) {
                    group = new TreeSet<Thing>(compareThings);
                    groups.put(obj.name, group);
                }
                group.add(obj);
            }
    
            // second pass
            SortedSet<SortedSet<Thing>> sortedGroups = new TreeSet<SortedSet<Thing>>(new Comparator<SortedSet<Thing>>() {
                public int compare(SortedSet<Thing> a, SortedSet<Thing> b) {
                    return compareThings.compare(a.last(), b.last());
                }
            });
            sortedGroups.addAll(groups.values());
            return sortedGroups;
        }
    
    }
    
    public class ScoreComparator implements Comparator<Item>
    {
    
      public int compare(Item a, Item b){
    
        if (a.name.equals(b.name){
          return a.score.compareTo(b.score);
        }
    
        return a.name.compareTo(b.Name);    
    
      }
    
    }