github.com/searKing/golang/go@v1.2.74/util/comparators.go (about) 1 // Copyright 2020 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package util 6 7 import "github.com/searKing/golang/go/util/object" 8 9 var NaturalOrderComparator = ComparableComparatorFunc(nil) 10 var ReverseOrderComparator = NaturalOrderComparator.Reversed() 11 12 type ComparableComparatorFunc func(a, b interface{}) int 13 14 func (f ComparableComparatorFunc) Compare(a, b interface{}) int { 15 if ac, ok := a.(Comparable); ok { 16 return ac.CompareTo(b) 17 } 18 if bc, ok := b.(Comparable); ok { 19 return -1 * bc.CompareTo(a) 20 } 21 object.RequireNonNil(f) 22 return f(a, b) 23 } 24 25 func (f ComparableComparatorFunc) Reversed() Comparator { 26 return ComparatorFunc(func(a, b interface{}) int { 27 return f.Compare(b, a) 28 }) 29 } 30 31 func (f ComparableComparatorFunc) ThenComparing(after Comparator) Comparator { 32 object.RequireNonNil(after) 33 return ComparatorFunc(func(a, b interface{}) int { 34 res := f.Compare(a, b) 35 if res != 0 { 36 return res 37 } 38 return after.Compare(a, b) 39 }) 40 } 41 42 // Null-friendly comparators 43 type NullComparator struct { 44 nilFirst bool 45 // if null, non-null Ts are considered equal 46 real Comparator 47 } 48 49 func NewNullComparator(nilFirst bool, real Comparator) *NullComparator { 50 return &NullComparator{ 51 nilFirst: nilFirst, 52 real: real, 53 } 54 } 55 56 func (n *NullComparator) Compare(a, b interface{}) int { 57 if a == nil && b == nil { 58 return 0 59 } 60 if a == nil { 61 if n.nilFirst { 62 return -1 63 } 64 return 1 65 } 66 67 if b == nil { 68 if n.nilFirst { 69 return 1 70 } 71 return -1 72 } 73 74 if n.real == nil { 75 return 0 76 } 77 78 return n.real.Compare(a, b) 79 } 80 81 func (n *NullComparator) ThenComparing(other Comparator) Comparator { 82 object.RequireNonNil(other) 83 84 if n.real == nil { 85 return other 86 } 87 return n.real.ThenComparing(other) 88 } 89 90 func (n *NullComparator) Reversed() Comparator { 91 if n.real == nil { 92 return &NullComparator{ 93 nilFirst: !n.nilFirst, 94 real: nil, 95 } 96 } 97 return &NullComparator{ 98 nilFirst: !n.nilFirst, 99 real: n.real.Reversed(), 100 } 101 }