この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

Newer Version Available

This content describes an older version of this product. View Latest

sObject のリストの並べ替え

List.sort メソッドを使用して、sObject のリストを並べ替えることができます。

sObject の場合、並べ替えは昇順で、次のセクションで説明する一連の比較ステップを使用します。sObject のカスタム並べ替え順は、Comparable インターフェースを実装する Apex クラスで sObject をラップして作成することができます。また、Comparator を実装するクラスをパラメーターとして並べ替えメソッドに渡して作成することもできます。「sObject のカスタム並べ替え順」を参照してください。

sObject のデフォルトの並べ替え順

List.sort メソッドは sObject を昇順で並べ替え、一連の順序付けられたステップに従って sObject を比較します。これらのステップには比較に使用される表示ラベルまたは項目が規定されています。比較は最初のステップから開始され、規定の表示ラベルまたは項目を使用して 2 つの sObject が並べ替えられたときに終了します。使用される比較の順序は次のようになります。
  1. sObject 型の表示ラベル。

    たとえば、Account sObject は Contact の前になります。

  2. Name 項目 (該当する場合)。

    たとえば、リストに Alpha と Beta という名前の 2 つの取引先がある場合、取引先 Alpha が取引先 Beta よりも前になります。

  3. 標準項目。ID 項目と Name 項目を除き、アルファベット順で最初の項目から使用されます。

    たとえば、2 つの取引先が同じ名前の場合、並べ替えに使用される最初の標準項目は AccountNumber です。

  4. カスタム項目。アルファベット順で最初の項目から使用されます。

    たとえば、2 つの取引先の名前と標準項目が同じで、FieldA と FieldB という 2 つのカスタム項目がある場合、並べ替えでは FieldA の値が最初に使用されます。

この一連のすべてのステップが実行されるとは限りません。たとえば、同じ種別で一意の Name 値がある 2 つの sObject がリストに含まれている場合、このリストは、Name 項目に基づいて並べ替えられ、並べ替えはステップ 2 で停止します。別の例で、名前が同じか sObject に Name 項目がない場合、並べ替えはステップ 3 まで進み、標準項目を基準に並べ替えられます。

テキスト項目の場合、並べ替えアルゴリズムは Unicode 並べ替え順を使用します。また、空の項目は並べ替え順で空でない項目より前になります。

Account sObject のリストの並べ替えの例を次に示します。この例では、Name 項目が使用されて、リスト内で Acme 取引先が 2 つの sForce 取引先より前に配置されることを示します。sForce という名前の取引先が 2 つあり、アルファベット順で Industry 項目は Site 項目より前になるため、Industry 項目が残りの取引先の並べ替えに使用されます。

1Account[] acctList = new List<Account>();        
2acctList.add( new Account(
3    Name='sForce',
4    Industry='Biotechnology',
5    Site='Austin'));
6acctList.add(new Account(
7    Name='sForce',
8    Industry='Agriculture',
9    Site='New York'));
10acctList.add(new Account(
11    Name='Acme'));
12System.debug(acctList);
13
14acctList.sort();
15Assert.areEqual('Acme', acctList[0].Name);
16Assert.areEqual('sForce', acctList[1].Name);
17Assert.areEqual('Agriculture', acctList[1].Industry);
18Assert.areEqual('sForce', acctList[2].Name);
19Assert.areEqual('Biotechnology', acctList[2].Industry);
20System.debug(acctList);

次の例は前の例と同様ですが、Merchandise__c カスタムオブジェクトを使用する点が異なります。この例では、Name 項目が使用されて、リスト内で Notebooks 商品が Pens より前に配置されることを示します。Name 項目値が Pens の商品 sObject が 2 つあるため、Description 項目が残りの商品品目の並べ替えに使用されます。Description 項目が並べ替えに使用されるのは、アルファベット順で Price 項目と Total_Inventory 項目の前になるためです。

1Merchandise__c[] merchList = new List<Merchandise__c>();        
2merchList.add( new Merchandise__c(
3    Name='Pens',
4    Description__c='Red pens',
5    Price__c=2,
6    Total_Inventory__c=1000));
7merchList.add( new Merchandise__c(
8    Name='Notebooks',
9    Description__c='Cool notebooks',
10    Price__c=3.50,
11    Total_Inventory__c=2000));
12merchList.add( new Merchandise__c(
13    Name='Pens',
14    Description__c='Blue pens',
15    Price__c=1.75,
16    Total_Inventory__c=800));
17System.debug(merchList);
18
19merchList.sort();
20Assert.areEqual('Notebooks', merchList[0].Name);
21Assert.areEqual('Pens', merchList[1].Name);
22Assert.areEqual('Blue pens', merchList[1].Description__c);
23Assert.areEqual('Pens', merchList[2].Name);
24Assert.areEqual('Red pens', merchList[2].Description__c);
25System.debug(merchList);

sObject のカスタム並べ替え順

リスト内の sObject のカスタム並べ替え順を作成するには、Comparator インターフェースを実装し、それをパラメーターとして List.sort メソッドに渡します。

sObject のラッパークラスを作成し、Comparable インターフェースを実装する方法もあります。ラッパークラスに対象の sObject を含め、並べ替えロジックを指定する Comparable.compareTo メソッドを実装します。

次の例では、Amount 項目に基づいて 2 つの商談を比較する Comparator インターフェースを実装します。

1public class OpportunityComparator implements Comparator<Opportunity> {
2    public Integer compare(Opportunity o1, Opportunity o2) {
3        // The return value of 0 indicates that both elements are equal.
4        Integer returnValue = 0;
5        
6        if(o1 == null && o2 == null) {
7            returnValue = 0;
8        } else if(o1 == null) {
9            // nulls-first implementation
10            returnValue = -1; 
11        } else if(o2 == null) {
12            // nulls-first implementation
13            returnValue = 1;
14        } else if ((o1.Amount == null) && (o2.Amount == null)) {
15            // both have null Amounts
16            returnValue = 0;
17        } else if (o1.Amount == null){
18            // nulls-first implementation
19            returnValue = -1;
20        } else if (o2.Amount == null){
21            // nulls-first implementation
22            returnValue = 1;
23        } else if (o1.Amount < o2.Amount) {
24            // Set return value to a negative value.
25            returnValue = -1;
26        } else if (o1.Amount > o2.Amount) {
27            // Set return value to a positive value.
28            returnValue = 1;
29        }
30        return returnValue;
31    }
32}

次のテストでは、Comparator オブジェクトのリストを並べ替え、リストの要素が商談金額を基準に並べ替えられていることを確認します。

1@isTest
2private class OpportunityComparator_Test {
3 
4    @isTest
5    static void sortViaComparator() {
6        // Add the opportunity wrapper objects to a list.
7        List<Opportunity> oppyList = new List<Opportunity>();
8        Date closeDate = Date.today().addDays(10);
9        oppyList.add( new Opportunity(
10            Name='Edge Installation',
11            CloseDate=closeDate,
12            StageName='Prospecting',
13            Amount=50000));
14        oppyList.add( new Opportunity(
15            Name='United Oil Installations',
16            CloseDate=closeDate,
17            StageName='Needs Analysis',
18            Amount=100000));
19        oppyList.add( new Opportunity(
20            Name='Grand Hotels SLA',
21            CloseDate=closeDate,
22            StageName='Prospecting',
23            Amount=25000));
24        oppyList.add(null);
25        
26        // Sort the objects using the Comparator implementation
27        oppyList.sort(new OpportunityComparator());
28        // Verify the sort order
29        Assert.isNull(oppyList[0]);
30        Assert.areEqual('Grand Hotels SLA', oppyList[1].Name);
31        Assert.areEqual(25000, oppyList[1].Amount);
32        Assert.areEqual('Edge Installation', oppyList[2].Name);
33        Assert.areEqual(50000, oppyList[2].Amount);
34        Assert.areEqual('United Oil Installations', oppyList[3].Name);
35        Assert.areEqual(100000, oppyList[3].Amount);
36        // Write the sorted list contents to the debug log.
37        System.debug(oppyList);
38    }
39}

次の例では、Opportunity のラッパークラス Comparable を作成する方法を示します。このクラスの compareTo メソッドの実装では、Amount 項目 (このインスタンスに含まれるクラスメンバー変数)、およびメソッドに渡された商談オブジェクトに基づいて 2 つの商談を比較します。

1public class OpportunityWrapper implements Comparable {
2
3    public Opportunity oppy;
4    
5    // Constructor
6    public OpportunityWrapper(Opportunity op) {
7    	// Guard against wrapping a null 
8    	if(op == null) {
9    		Exception ex = new NullPointerException();
10    		ex.setMessage('Opportunity argument cannot be null'); 
11    		throw ex;
12    	}
13        oppy = op;
14    }
15    
16    // Compare opportunities based on the opportunity amount.
17    public Integer compareTo(Object compareTo) {
18        // Cast argument to OpportunityWrapper
19        OpportunityWrapper compareToOppy = (OpportunityWrapper)compareTo;
20        
21        // The return value of 0 indicates that both elements are equal.
22        Integer returnValue = 0;
23        if ((oppy.Amount == null) && (compareToOppy.oppy.Amount == null)) {
24            // both wrappers have null Amounts
25            returnValue = 0;
26        } else if ((oppy.Amount == null) && (compareToOppy.oppy.Amount != null)){
27            // nulls-first implementation
28            returnValue = -1;
29        } else if ((oppy.Amount != null) && (compareToOppy.oppy.Amount == null)){
30            // nulls-first implementation
31            returnValue = 1;
32        } else if (oppy.Amount > compareToOppy.oppy.Amount) {
33            // Set return value to a positive value.
34            returnValue = 1;
35        } else if (oppy.Amount < compareToOppy.oppy.Amount) {
36            // Set return value to a negative value.
37            returnValue = -1;
38        } 
39        return returnValue;
40    }
41}

次のテストでは、OpportunityWrapper オブジェクトのリストを並べ替え、リストの要素が商談金額を基準に並べ替えられていることを確認します。

1@isTest 
2private class OpportunityWrapperTest {
3    static testmethod void test1() {
4        // Add the opportunity wrapper objects to a list.
5        OpportunityWrapper[] oppyList = new List<OpportunityWrapper>();
6        Date closeDate = Date.today().addDays(10);
7        oppyList.add( new OpportunityWrapper(new Opportunity(
8            Name='Edge Installation',
9            CloseDate=closeDate,
10            StageName='Prospecting',
11            Amount=50000)));
12        oppyList.add( new OpportunityWrapper(new Opportunity(
13            Name='United Oil Installations',
14            CloseDate=closeDate,
15            StageName='Needs Analysis',
16            Amount=100000)));
17        oppyList.add( new OpportunityWrapper(new Opportunity(
18            Name='Grand Hotels SLA',
19            CloseDate=closeDate,
20            StageName='Prospecting',
21            Amount=25000)));
22        
23        // Sort the wrapper objects using the implementation of the 
24        // compareTo method.
25        oppyList.sort();
26        
27        // Verify the sort order
28        Assert.areEqual('Grand Hotels SLA', oppyList[0].oppy.Name);
29        Assert.areEqual(25000, oppyList[0].oppy.Amount);
30        Assert.areEqual('Edge Installation', oppyList[1].oppy.Name);
31        Assert.areEqual(50000, oppyList[1].oppy.Amount);
32        Assert.areEqual('United Oil Installations', oppyList[2].oppy.Name);
33        Assert.areEqual(100000, oppyList[2].oppy.Amount);
34        
35        // Write the sorted list contents to the debug log.
36        System.debug(oppyList);
37    }
38}