C\#의 List.ort()--집합 정렬 방법 전면 분석

13915 단어 C#List.Sort정렬
C\#에서 List.ort()는 기본 적 인 정렬 방법 을 제공 할 뿐만 아니 라 4 가지 사용자 정의 정렬 방법 도 제공 합 니 다.기본 정렬 방법 을 통 해 저 희 는 Sort()방법의 실현 코드 를 다시 쓰 지 않 아 도 단일 매개 변수 형식의 List 데 이 터 를 단일 규칙 으로 정렬 할 수 있 습 니 다.이런 방법 을 개선 하면 다 중 매개 변수,다 중 규칙 의 복잡 한 정렬.
다음은 C\#사용자 정의 정렬 방법 4 가지 입 니 다.

List<T>.Sort();   
List<T>.Sort(IComparer<T> Comparer);
List<T>.Sort(int index, int count, IComparer<T> Comparer);
List<T>.Sort(Comparison<T> comparison);
목 표를 달성 하 다
만약 에 하나의 People 클래스 가 존재 한다 고 가정 하면 Name,Age 속성 을 포함 하고 클 라 이언 트 에서 List 를 만들어 여러 개의 인 스 턴 스 를 저장 합 니 다.List 의 내용 을 Name 과 Age 매개 변수 에 따라 정렬 하고 자 합 니 다.정렬 규칙 은 이름 의 오름차 순 으로 정렬 합 니 다.이름 이 같 으 면 나이 의 오름차 순 으로 정렬 합 니 다.

class People
{
 public People(string name, int age) { Name = name; Age = age; }
 public string Name { get; set; } //  
 public int Age { get; set; } //  
}
 
//    
class Client
{
 static void Main(string[] args)
 {
  List<People> peopleList = new List<People>();
  peopleList.Add(new People("  ", 22));
  peopleList.Add(new People("  ", 24));
  peopleList.Add(new People("  ", 18));
  peopleList.Add(new People("  ", 16));
  peopleList.Add(new People("  ", 30));
 }
}
방법 1.People 류 에 대해 IComparable 인 터 페 이 스 를 계승 하여 CompareTo()방법 을 실현 한다.
이 방법 은 시스템 의 기본 적 인 방법 으로 단일 매개 변수 일 때 기본적으로 오름차 순 서 를 정렬 합 니 다.그러나 다 중 인자(Name,Age)정렬 을 만 났 을 때 이 기본 방법 을 수정 해 야 합 니 다.
방법 1:People 류 가 IComparable 인 터 페 이 스 를 계승 하여 CompareTo()방법 실현
IComparable:값 형식 이나 클래스 로 이 루어 진 일반적인 비교 방법 을 정의 합 니 다.특정한 유형의 비교 방법 을 만들어 서 실례 를 정렬 하 는 데 목적 을 둡 니 다.
원리:자체 적 으로 실현 되 는 CompareTo()방법 은 list.ort()내부 에서 요소 두 가 지 를 비교 하여 최종 적 으로 정렬 을 실현 한다.

class People : IComparable<People>
{
 public People(string name, int age) { Name = name;Age = age; }
 public string Name { get; set; }
 public int Age { get; set; }
 
 // list.Sort()     CompareTo()       
 public int CompareTo(People other)
 {
  if (this.Name != other.Name)
  {
   return this.Name.CompareTo(other.Name);
  }
  else if (this.Age != other.Age)
  {
   return this.Age.CompareTo(other.Age);
  }
  else return 0;
 }
}
 
//    
peopleList.Sort();
 
// OUTPUT:
//     18
//     16
//     30
//     22
//     24
방법 2:People 류 의 외부 비교 류 를 증가 하고 IComparer 인 터 페 이 스 를 계승 하여 compare()방법 을 실현 한다.
상기 IComparable 을 계승 하 는 방법 과 달리 이 방법 은 People 내 에서 IComparer 인 터 페 이 스 를 계승 하여 실현 할 수 없고 새로운 비교 방법 류 로 인 터 페 이 스 를 실현 해 야 한다.
방법 2:새로운 People Comparer 류,IComparer 인 터 페 이 스 를 계승 하고 compare()방법 실현
원리:list.ort()는 People Comparer 류 의 인 스 턴 스 를 매개 변수 로 하고 내부 에서 Compare()방법 으로 두 가지 비 교 를 한 다음 에 정렬 을 실현 합 니 다(주:상기 방법 은 CompareTo()이 고 여 기 는 Compare()방법 입 니 다).

//         
class PeopleComparer : IComparer<People>
{
 //    CompareTo()   ,      
 public int Compare(People x, People y)
 {
  if (x.Name != y.Name)
  {
   return x.Name.CompareTo(y.Name);
  }
  else if (x.Age != y.Age)
  {
   return x.Age.CompareTo(y.Age);
  }
  else return 0;
 }
}
 
//    
//                  
peopleList.Sort(new PeopleComparer());
 
// OUTPUT:
//     18
//     16
//     30
//     22
//     24
마찬가지 로 List.ort(int index,int count,IComparerComparer)방법의 매개 변수:대기 요소 시작 색인,대기 요소 개수,정렬 방법
방법 3.일반적인 의뢰 Comparison를 사용 하여 사용자 정의 비교 방법 을 연결 합 니 다.
상기 계승 인터페이스 와 구별 되 는 방법 입 니 다.이 방법의 매개 변 수 는 일반적인 의뢰 Comparison입 니 다.
위탁 원형:public delegate int Comparison(T x,T y);
방법 3:의뢰 의 사용 방법 에 따라 먼저 의뢰 인 스 턴 스 MyComparison 을 만 들 고 사용자 정의 비교 방법 인 People Comparison()에 연결 하여 list.ort()를 호출 할 때 의뢰 인 스 턴 스 를 전송 합 니 다.
원리:list.ort()는 들 어 오 는 의뢰 방법 에 따라 두 가지 요 소 를 비교 하여 최종 적 으로 정렬 합 니 다.

//    
class Client
{
 //   0        
 public static int PeopleComparison(People p1, People p2)
 {
  if (p1.Name != p2.Name)
  {
   return p1.Name.CompareTo(p2.Name);
  }
  else if (p1.Age != p2.Age)
  {
   return p1.Age.CompareTo(p2.Age);
  }
  else return 0;
 }
 
 static void Main(string[] args)
 {
  /   list ... /
  
  //   0          
  Comparison<People> MyComparison = PeopleComparison;
 
  //            
  peopleList.Sort(MyComparison);
 
  // OUTPUT:
  //     18
  //     16
  //     30
  //     22
  //     24
 }
}
또한 Comparison가 일반적인 의뢰 인 이상 Lambda 표현 식 으로 설명 할 수 있 습 니 다.

// Lambda     Comparison  
peopleList.Sort((p1, p2) =>
{
 if (p1.Name != p2.Name)
 {
  return p2.Name.CompareTo(p1.Name);
 }
 else if (p1.Age != p2.Age)
 {
  return p2.Age.CompareTo(p1.Age);
 }
 else return 0;
});
 
// OUTPUT:
//     24
//     22
//     30
//     16
//     18
총결산
본 고 는 List의 한 용기 만 사용 하여 Sort()방법 을 논술 하 였 으 나 서로 다른 용기 의 Sort()를 사용 하 는 방법 은 현저 한 차이 가 있 습 니 다.핵심 원 리 는 두 가지 인터페이스 와 범 형 의뢰 를 응용 하 는 것 이기 때 문 입 니 다.
두 가지 인터페이스:IComparable,IComparer
일반 의뢰:Comparison
레 퍼 런 스
IComparable 인터페이스-Microsoft
비교 의뢰-Microsoft
IComparer 인터페이스-Microsoft
첨부:완전한 테스트 데모

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; 
namespace ListSort
{
 class Program
 {
  static void DisplayInfo<T>(List<T> list) {
   //  List    
   foreach(var item in list) {
    System.Console.Write("{0} ",item.ToString());
   }
   System.Console.WriteLine("");
  }
 
  //   3            
  public static int PeopleComparison(People p1, People p2)
  {
   if (p1.Name != p2.Name)
   {
    return p1.Name.CompareTo(p2.Name);
   }
   else if (p1.Age != p2.Age)
   {
    return p1.Age.CompareTo(p2.Age);
   }
   else return 0;
  }
  static void Main(string[] args)
  {
   List<People> peopleList = new List<People>();
   peopleList.Add(new People("  ", 22));
   peopleList.Add(new People("  ", 24));
   peopleList.Add(new People("  ", 18));
   peopleList.Add(new People("  ", 16));
   peopleList.Add(new People("  ", 30));
 
   System.Console.WriteLine("       :");
   DisplayInfo(peopleList);
   System.Console.WriteLine("------------------------------------");
 
   System.Console.WriteLine("  1     :");
   peopleList.Sort();
   DisplayInfo(peopleList);
 
   System.Console.WriteLine("  2     :");
   DisplayInfo(peopleList);
 
   //   1   IComparer<T>  。
   peopleList.Sort(new PeopleComparer());
 
   //   2                    , People    IComparable<T>
   peopleList.Sort();
   System.Console.WriteLine("  3     :");
   DisplayInfo(peopleList);
 
   //   3            
   Comparison<People> MyComparison = PeopleComparison;
 
   //            
   peopleList.Sort(MyComparison);
 
   System.Console.WriteLine("  3     :");
   DisplayInfo(peopleList);
 
   //   3   Comparison<T>  ,Lambda  
   peopleList.Sort((left, right) =>
   {
    //      ,            
    int x = left.Name.CompareTo(right.Name);
    if(x==0) {
     if (left.Age > right.Age)
      x = 1;
     else if (left.Age == right.Age)
      x = 0;
     else
      x = -1;
    }
    return x;
   }); 
  }
 }
 
  //   
 public class People : IComparable<People>
 {
  public int Age { get;set;}
  public string Name { get;set;}
  public People(string name,int age) {
   this.Name = name;
   this.Age = age;
  }
 
  public override string ToString() {
   string result = "";
   result = "["+this.Name+","+ this.Age.ToString()+"]";
   return result; 
  }
 
  public int CompareTo(People other)
  {
   int x = this.Name.CompareTo(other.Name);
   if(x==0) {
    if (this.Age > other.Age)
     x = 1;
    else if (this.Age == other.Age)
     x = 0;
    else
     x = -1;
   }
   return x;
  }
 }
 
 //   
 public class PeopleComparer : IComparer<People>
 {
  public int Compare(People left, People right)
  {
   int x = left.Name.CompareTo(right.Name);
   if(x==0) {
    if (left.Age > right.Age)
     x = 1;
    else if (left.Age == right.Age)
     x = 0;
    else
     x = -1;
   }
   return x;
  }
 } 
} 
보충:C\#IComparable 과 IComparer 인터페이스 와 사용자 정의 비교 기
머리말
Array List 에 방법 이 있 습 니 다.

public virtual void Sort(IComparer comparer);
지정 한 비교 기 를 사용 하여 전체 System.collections.Array List 의 요 소 를 정렬 합 니 다.
comparer:요 소 를 비교 할 때 사용 할 System.collections.IComparer 가 실 현 됩 니 다.
뭐야?
본문
1.Comparer 클래스 에 대한 간단 한 소개
이것 을 알 고 싶 으 면,우 리 는 먼저 이런 종 류 를 보 자.
System.collections 이름 공간 에 이러한 종류 가 있 습 니 다:Comparer.말 그대로 그 는 간단 한 유형 에 대한 비 교 를 실현 할 수 있다.무슨 뜻 일 까?다음 코드 를 보십시오.

int a=1,b=2;
정상 적 인 상황 에서 우 리 는 어떻게 그들의 크기 를 비교 해 야 합 니까?if,연산 자,...?이것 은 물론 입 니 다.그러나 Comparer 는 우리 에 게 함 수 를 제공 해 주 었 습 니 다.직접 사용 할 수 있 습 니 다.(using System.collections 가 필요 합 니 다.)

Console.WriteLine(Comparer.Default.Compare(a,b));
aComparer 의 정적 속성 Default 를 통 해 Comparer 의 인 스 턴 스 를 얻 고 Comparer 의 비 정적 함수 Compare 를 호출 합 니 다.
(알파벳 에 따라 두 개의 string 유형 을 비교 할 수 있 습 니 다.여기 서 간략하게 소개 합 니 다)
2.사용자 정의 비교 기,IComparable,IComparer 인터페이스
물론 이 종 류 는 두 수의 크기 만 비교 하 는 것 이 아니다.때때로 우 리 는 두 대상 을 직접 비교 하고 싶 지만,안의 속성 을 인용 하 는 것 은 아마도 비교적 번 거 로 울 것 이다.특히 참고 요소 가 너무 많아 직접 비교 하기 어 려 울 때 어떻게 해 야 두 대상 을 더욱 효율적으로 비교 할 수 있 습 니까?이 럴 때 우 리 는 사용자 정의 비교 기 가 필요 하 다.
우선 IComparable 인 터 페 이 스 를 소개 합 니 다.이 인터페이스 에는 CompareTo()방법 이 하나 밖 에 없다.이 인 터 페 이 스 를 실현 하 는 CompareTo 방법 은 이 방법 을 다른 대상 과 직접 비교 할 수 있 습 니 다.다음은 예 입 니 다.

public class ClassTest : IComparable
{
 public int intTest;
 public int CompareTo(object obj)
 {
 return intTest-((ClassTest)obj).intTest;
 //              ,           
 }
}
그리고 바로 사용 할 수 있 습 니 다.

ClassTest a = new ClassTest(){intTest=1};
ClassTest b = new ClassTest(){intTest=2};
Console.WriteLine(a.CompareTo(b));//  -1
Comparer         IComparer     ,           。     :(  using System.Collections;)
public class ClassTestComparer : IComparer
{
 public static IComparer Default = new ClassTestComparer();
 //           ,      IComparer       ,     
 public int Compare(object a,object b)
 {
 return ((ClassTest)a).intTest - ((ClassTest)b).intTest;
 //            ,         
 }
}
비교 에 사용 되 는 클래스 와 설정 에 사용 되 는 클래스 가 다 르 면 오류 가 발생 할 수 있 습 니 다.
사용 예시:

ClassTest a = new ClassTest(){intTest=1};
ClassTest b = new ClassTest(){intTest=2};
Console.WriteLine(ClassTestComparer.Default.Compare(a,b));
//   -1
이 두 인터페이스의 차이 점 은 IComparable 이 비교 할 대상 의 클래스 에서 실현 되 고 이 대상 과 다른 대상 을 비교 할 수 있다 는 것 이다.IComparer 는 하나의 단독 클래스 에서 이 루어 집 니 다.임의의 두 대상 을 비교 할 수 있 습 니 다.(관건 은 설정 입 니 다.)
3.집합 정렬
물론 이 두 인 터 페 이 스 는 더 강력 한 용도 가 있다.우 리 는 이 두 개의 인 터 페 이 스 를 사용 하여 집합 을 정렬 할 수 있다.앞에서 말 한 Sort()방법 기억 나 세 요?다음은 Array List 를 예 로 들 어 어떻게 사용 하 는 지 소개 한다.

ArrayList ClassTests = new ArrayList();
ClassTest a = new ClassTest(){intTest=1};
ClassTest b = new ClassTest(){intTest=2};
ClassTest c = new ClassTest(){intTest=3};
ClassTests.Add(a);
ClassTests.Add(b);
ClassTests.Add(c);
ClassTests.Sort();
//     Sort,      CompareTo()  ,  ClassTest       ,        。      ,      。
ClassTests.Sort(ClassTestComparer.Default);
//    Compare()           。ClassTestComparer        ,       IComparer     。
주의해 야 할 것 은:
두 인터페이스 가 제공 하 는 방법 반환 값 은 모두 int 형식 이 고 마이너스 대 표 는 적 으 며 0 대 표 는 같 으 며 정수 대 표 는 크다.따라서 숫자 이외 의 사용자 정의 비교 기 는'큰'이 무엇 인지,'작은'이 무엇 인지 인공 적 으로 설정 해 야 한다.그래서 위의 예제 에서 두 개의 수 를 직접 줄 이면 크기 를 비교 할 수 있다.
정렬 이 끝 난 후 돌아 오 는 int 값 에 따라 집합 은 작은 것 에서 큰 것 으로 배열 된다.
무 참 Sort()를 사용 할 때 집합 에서 최소한 한 가지 클래스 가 IComparable 을 실현 해 야 합 니 다.그렇지 않 으 면 오 류 를 보고 할 수 있 습 니 다.
일반적으로 같은 종 류 를 비교 하 는 것 이다.그러나 서로 다른 비교 코드 도 실현 할 수 있다.이것 은 구체 적 인 수요 에 달 려 있다.
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.만약 잘못 이 있 거나 완전히 고려 하지 않 은 부분 이 있다 면 아낌없이 가르침 을 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기