【问题标题】:Sorting a JSON based on date根据日期对 JSON 进行排序
【发布时间】:2019-12-24 11:23:39
【问题描述】:

我想根据期间内的日期对 json 进行排序,但它还包含其他字符串(MAT TY 和 MAT YA)值,我们必须始终保留在列表的前面(首先是 MAT TY,然后是 MAT YA)和之后的排序项目,我该怎么做?这是 JSON 响应:

 [{

        "Period": "MAT YA",
        "StartUnit": null,
        "EndUnit": null,

    },
    {

        "Period": "DEC 2018",
        "StartUnit": null,
        "EndUnit": null,

    },
    {

        "Period": "NOV 2018",
        "StartUnit": null,
        "EndUnit": null,

    },
    {

        "Period": "SEP 2018",
        "StartUnit": null,
        "EndUnit": null,

    },
    {

        "Period": "JUN 2019",
        "StartUnit": null,
        "EndUnit": null,

    },
    {

        "Period": "MAT TY",
        "StartUnit": null,
        "EndUnit": null,
    },
    {

        "Period": "MAT YA",
        "StartUnit": null,
        "EndUnit": null,

    },
    {

        "Period": "MAT YA",
        "StartUnit": null,
        "EndUnit": null,

    },
    {

        "Period": "MAT TY",
        "StartUnit": null,
        "EndUnit": null,

    }
]

我知道 Comparator 是这样的:

myDateList.sortWith(Comparator { s1, s2 -> myDateList.indexOf(s1).compareTo(myDateList.indexOf(s2))})

那么我怎样才能将它转换为满足上述要求呢?

更新自定义比较器

 private fun customSortFunction(mydateList: ArrayList<String>){
        val sdf = SimpleDateFormat("MMM yyyy")
        val comparator = Comparator<String> { date1, date2 ->
            if (date1 == "MAT TY") return@Comparator -1
            if (date2 == "MAT TY") return@Comparator 1
            if (date1 == "MAT YA") return@Comparator -1
            if (date2 == "MAT YA") return@Comparator 1

            val date1Formatted = sdf.parse(date1)
            val date2Formatted = sdf.parse(date2)
            return@Comparator date1Formatted.compareTo(date2Formatted)
        }

        mydateList.sortWith(comparator)
        Log.e(TAG, "Date list: "+ mydateList)
    }

堆栈跟踪

 java.lang.IllegalArgumentException: Comparison method violates its general contract!
        at java.util.TimSort.mergeHi(TimSort.java:899)
        at java.util.TimSort.mergeAt(TimSort.java:516)
        at java.util.TimSort.mergeCollapse(TimSort.java:441)
        at java.util.TimSort.sort(TimSort.java:245)
        at java.util.Arrays.sort(Arrays.java:1523)
        at java.util.Collections.sort(Collections.java:238)
        at kotlin.collections.CollectionsKt__MutableCollectionsJVMKt.sortWith(MutableCollectionsJVM.kt:34)
        at com.abc.ShareStoryFragment.customSortFunction(ShareStoryFragment.kt:429)

第429行是:

mydateList.sortWith(comparator)

Mydatelist 值:

[SEP 2019, JUL 2019, AUG 2019, JUN 2019, MAY 2019, APR 2019, MAT TY, MAR 2019, FEB 2019, MAT YA, NOV 2018, SEP 2018, DEC 2018, OCT 2018, JAN 2019, FEB 2019, SEP 2018, JAN 2019, NOV 2018, OCT 2018, DEC 2018, MAT YA, MAT YA, NOV 2018, MAR 2019, MAT TY, SEP 2018, OCT 2018, DEC 2018, APR 2019, JUL 2019, APR 2019, SEP 2019, AUG 2019, MAY 2019, AUG 2019, MAT TY, JAN 2019, FEB 2019, JUN 2019, MAR 2019, MAY 2019, SEP 2019, JUL 2019, JUN 2019, APR 2019, MAR 2019, FEB 2019, MAY 2019, JAN 2019, MAT YA, MAT TY, AUG 2019, DEC 2018, SEP 2019, JUL 2019, NOV 2018, JUN 2019, SEP 2018, OCT 2018, SEP 2019, AUG 2019, JUL 2019, MAY 2019, APR 2019, JUN 2019, MAT TY, MAR 2019, FEB 2019, MAT YA, DEC 2018, OCT 2018, NOV 2018, JAN 2019, SEP 2018, MAT YA, SEP 2018, DEC 2018, OCT 2018, NOV 2018, FEB 2019, JAN 2019, MAR 2019, APR 2019, MAT TY, JUL 2019, MAY 2019, JUN 2019, SEP 2019, AUG 2019, JUN 2019, AUG 2019, SEP 2019, OCT 2018, JUL 2019, SEP 2018, MAY 2019, MAT TY, JAN 2019, NOV 2018, DEC 2018, FEB 2019, MAR 2019, APR 2019, MAT YA]

请帮忙。

【问题讨论】:

  • json生成模型并对列表进行排序
  • @Md.Asaduzzaman 我可以进行正常排序,但如何将 MAT TY 值保持在顶部,并且日期仅采用月年格式。
  • 您可以在自定义比较器中创建特殊情况。您能否发布有关如何对列表进行排序的代码?
  • @Christilyn 请检查一下
  • 试试docs.oracle.com/javase/8/docs/api/java/time/…... 这会将其解析为 YearMonth。您只需要制作 DateTimeFormatter。

标签: java android kotlin


【解决方案1】:

does not follow the contract 描述的比较逻辑。如果当两个字符串都是“MAT YA”或“MAT TY”时没有分支覆盖,您可能会遇到 A > B 和 B > A 的情况。当两个字符串相同时,您需要在顶部处理另一个条件:

private val val sdf = SimpleDateFormat("MMM yyyy")

fun compare(s1: String?, s2: String?): Int = when {
  s1 == s2 -> 0
  s1 == "MAT TY" -> -1
  s2 == "MAT TY" -> 1
  s1 == "MAT YA" -> -1
  s2 == "MAT YA" -> 1
  s1 == null -> 1
  s2 == null -> -1
  else -> sdf.parse(s1).compareTo(sdf.parse(s2))
}

【讨论】:

    【解决方案2】:

    这是一个满足您需求的自定义比较器:

    val sdf = SimpleDateFormat("MMM yyyy")
    val stringList = arrayListOf(
            "JUN 2019",
            "MAT YA",
            "SEP 2018",
            "MAT YA",
            "MAT TY",
            "NOV 2018"
    )
    
    val comparator = Comparator<String> { date1, date2 ->
        if (date1 == "MAT TY") return@Comparator -1
        if (date2 == "MAT TY") return@Comparator 1
        if (date1 == "MAT YA") return@Comparator -1
        if (date2 == "MAT YA") return@Comparator 1
    
        val date1Formatted = sdf.parse(date1)
        val date2Formatted = sdf.parse(date2)
        return@Comparator date1Formatted.compareTo(date2Formatted)
    }
    
    stringList.sortWith(comparator)
    println(stringList)
    

    这会导致:

    [MAT TY, MAT YA, MAT YA, SEP 2018, NOV 2018, JUN 2019]
    

    【讨论】:

    • 那么对日期进行排序呢? 2018 年 11 月应该早于 2019 年 6 月
    • @CosmicDev 我已经编辑了我的答案以考虑实际日期比较。希望对你有帮助
    • 得到一个错误:java.lang.IllegalArgumentException:比较方法违反了它的一般约定!
    • @CosmicDev 你在哪一行得到错误?另外,你能不能用你的新实现来更新你的帖子,这样我就可以看到了
    • 刚刚请检查
    猜你喜欢
    • 2017-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-02
    • 1970-01-01
    • 2022-09-23
    相关资源
    最近更新 更多