Java 对字符串排序并解析为列表

Java 对字符串排序并解析为列表,java,sorting,parsing,Java,Sorting,Parsing,我有一个包含名称和评级的字符串,我想根据评级按从高到低的方式对它们进行排序。评级将始终为正数 字符串如下所示: "john;q=1, david;q=0, scott, robert, bob;q=0.5" 如果名称没有值,则它应该是排序顺序中的最后一个。我还想将此字符串拆分为一个列表。因此,应将上述字符串解析为: ["john", "bob", "david", "scott", "

我有一个包含名称和评级的字符串,我想根据评级按从高到低的方式对它们进行排序。评级将始终为正数

字符串如下所示:

"john;q=1, david;q=0, scott, robert, bob;q=0.5"
如果名称没有值,则它应该是排序顺序中的最后一个。我还想将此字符串拆分为一个列表。因此,应将上述字符串解析为:

["john", "bob", "david", "scott", "robert"]
注意:“scott”和“robert”的顺序应与原始字符串中的顺序相同

我现在就是这样做的:

private List<String> parseString(final String str) {
    Map<String, List<String>> map = new TreeMap<>(Collections.reverseOrder());
    String[] acceptHeaders = str.replace(" ", "").split(",");

    for (String header : acceptHeaders) {
        if (header.contains(";")) {
            int equalIndex = header.indexOf("=");
            String value = header.substring(equalIndex + 1, header.length());
            String name = header.substring(0, equalIndex-2);
            if (map.containsKey(value)) {
                List<String> val = map.get(value);
                val.add(name);
                map.put(value, val);
            } else {
                List<String> val = new ArrayList<>();
                val.add(name);
                map.put(value, val);
            }
        } else {
            if (!map.containsKey("-1")) {
                map.put("-1", new ArrayList<>());
            }
            List<String> val = map.get("-1");
            val.add(header);
            map.put("-1", val);
        }
    }

    return map.values().stream().flatMap(List::stream).collect(Collectors.toList());;
}
私有列表解析字符串(最终字符串str){
Map Map=newtreemap(Collections.reverseOrder());
字符串[]acceptHeaders=str.replace(“,”).split(“,”);
for(字符串头:acceptHeaders){
if(标题.包含(;)){
int equalIndex=头文件。indexOf(“=”);
字符串值=header.substring(equalIndex+1,header.length());
字符串名称=头.子字符串(0,equalIndex-2);
if(映射容器(值)){
List val=map.get(值);
val.add(名称);
map.put(值,val);
}否则{
List val=new ArrayList();
val.add(名称);
map.put(值,val);
}
}否则{
如果(!map.containsKey(“-1”)){
map.put(“-1”,新的ArrayList());
}
List val=map.get(“-1”);
val.add(表头);
地图放置(“-1”,val);
}
}
返回map.values().stream().flatMap(List::stream).collect(Collectors.toList());;
}
在java中是否有更好/更干净的方法来实现这一点

  • 将所有字符串插入ArrarList

  • 使用Collections.Sort()或Java 8中的等效项对该ArrayList进行排序。在sort()方法中传递一个比较器,并在该比较器的compare()方法中写入逻辑,如determinate rating并相应地返回

  • 我不确定这是否会更干净,但我想到了这种方法。

    公共类比较器{
    
    public class Comparator {
    
    public static class NewClass implements  Comparable<NewClass>{
        public String s;
        public float rating;
    
        public NewClass(String s) {
            String[] split = s.split(";q=");
            this.s = split[0];
            if(split.length > 1){
                this.rating = Float.parseFloat(split[1]);
            }else{
                this.rating = -1f;
            }
        }
        @Override
        public int compareTo(NewClass o) {
            return Float.compare(o.rating, this.rating); //sorting in descending order
        }
    }
    
    public static void main(String[] args) {
        String[] input = new String[]{"john;q=1", "david;q=0", "scott", "robert", "bob;q=0.5"};
        ArrayList<NewClass> items = new ArrayList<>();
        for(String s : input){
            items.add(new NewClass(s));
        }
        Collections.sort(items);
        String[] output = new String[input.length];
        int count= 0;
        for(NewClass item : items){
            output[count++] = item.s;
        }
        System.out.println(Arrays.toString(output));
    }
    
    公共静态类NewClass实现了可比较的{ 公共字符串s; 公众浮动评级; 公共NewClass(字符串s){ String[]split=s.split(“;q=”); 此.s=拆分[0]; 如果(拆分长度>1){ this.rating=Float.parseFloat(拆分[1]); }否则{ 这一等级=-1f; } } @凌驾 公共整数比较(新o类){ 返回Float.compare(o.rating,this.rating);//按降序排序 } } 公共静态void main(字符串[]args){ 字符串[]输入=新字符串[]{“john;q=1”、“david;q=0”、“scott”、“robert”、“bob;q=0.5”}; ArrayList items=新建ArrayList(); for(字符串s:输入){ 添加(新类别); } 收集.分类(项目); String[]输出=新字符串[input.length]; 整数计数=0; 用于(新类项目:项目){ 输出[count++]=item.s; } System.out.println(Arrays.toString(output)); }
    我创建了一个新类,并使用Comparable接口使用rating对项目进行排序。如果未给出评级,我假设它为-1。您可以在此处使用任何值。

    请参见以下内容:

        TreeMap<Float, String> map = new TreeMap<>(Collections.reverseOrder());
        for (String user : input.split(", ")) {
            String[] split = user.split(";q=");
            map.put(split.length == 1 ? (map.lastKey() - 1f) : Float.valueOf(split[1]), split[0]);
        }
        return map.values();
    
    TreeMap map=newtreemap(Collections.reverseOrder());
    for(字符串用户:input.split(“,”)){
    String[]split=user.split(“;q=”);
    map.put(split.length==1?(map.lastKey()-1f):Float.valueOf(split[1]),split[0]);
    }
    返回map.values();
    
    还有比这更好的解决办法吗

  • 创建一个名为Client/Student的类
  • 解析字符串并创建客户机/学生对象,然后将其放入列表
    ArrayList devList
  • 然后使用
    Collections.sort()
  • DevStuden类:

    class DevStudent{
        String name;
        double rating;
        
        public DevStudent(String name,double rating){
            this.name = name;
            this.rating = rating;
        }   
    }
    
    使用集合排序。排序:

    List<DevStudent> devList = new ArrayList<DevStudent>();
    //populate devList
    //then sort
    Collections.sort(devList, new Comparator<DevStudent>() {
       @Override
       public int compare(DevStudent c1, DevStudent c2) {
          return Double.compare(c2.rating, c1.rating);
        }
    });
    
    List devList=new ArrayList();
    //填充devList
    //然后分类
    Collections.sort(devList,newcomparator(){
    @凌驾
    公共整数比较(DevStudent c1、DevStudent c2){
    返回双重比较(c2.rating,c1.rating);
    }
    });
    
    以逗号分隔的值列表,其中值有一个可选的
    ;q=
    和一个范围为0-1的数字。这看起来是HTTP头的值,瞧,您有一个名为
    acceptHeaders
    的局部变量。您为什么试图将其称为其他值?---不管怎样,您说“没有值,它应该是排序顺序中的最后一个”,但HTTP规范说“如果不存在,默认值是1“,这意味着它应该首先与带有显式
    ;q=1
    质量值的任何值一起排序。谢谢@Andreas,但是你对我如何清理代码以实现我正在做的事情有什么建议吗?这看起来很棒。谢谢!编辑:)借助map.lastKey()更简洁树门中的方法在以下情况下不起作用:1)有多个值具有相同的q值。2)第一个值没有q值。3)有多个值没有q值。1:拆分仍然提供原始字符串。
    compareTo()
    错误。应该是
    返回Float.compare(o.rating,this.rating);//降序
    。注释用于记录
    o
    this
    的反转是有意的,这会导致降序排序。