private List < String > initLabels ( ) { Normalizer2 nfkdNormalizer = Normalizer2 . getNFKDInstance ( ) ; List < String > indexCharacters = new ArrayList < String > ( ) ; String firstScriptBoundary = firstCharsInScripts . get ( 0 ) ; String overflowBoundary = firstCharsInScripts . get ( firstCharsInScripts . size ( ) - 1 ) ; // We make a sorted array of elements. // Some of the input may be redundant. // That is, we might have c, ch, d, where "ch" sorts just like "c", "h". // We filter out those cases. for ( String item : initialLabels ) { boolean checkDistinct ; if ( ! UTF16 . hasMoreCodePointsThan ( item , 1 ) ) { checkDistinct = false ; } else if ( item . charAt ( item . length ( ) - 1 ) == ' ' && item . charAt ( item . length ( ) - 2 ) != ' ' ) { // Use a label if it is marked with one trailing star, // even if the label string sorts the same when all contractions are suppressed. item = item . substring ( 0 , item . length ( ) - 1 ) ; checkDistinct = false ; } else { checkDistinct = true ; } if ( collatorPrimaryOnly . compare ( item , firstScriptBoundary ) < 0 ) { // Ignore a primary-ignorable or non-alphabetic index character. } else if ( collatorPrimaryOnly . compare ( item , overflowBoundary ) >= 0 ) { // Ignore an index character that will land in the overflow bucket. } else if ( checkDistinct && collatorPrimaryOnly . compare ( item , separated ( item ) ) == 0 ) { // Ignore a multi-code point index character that does not sort distinctly // from the sequence of its separate characters. } else { int insertionPoint = Collections . binarySearch ( indexCharacters , item , collatorPrimaryOnly ) ; if ( insertionPoint < 0 ) { indexCharacters . add ( ~ insertionPoint , item ) ; } else { String itemAlreadyIn = indexCharacters . get ( insertionPoint ) ; if ( isOneLabelBetterThanOther ( nfkdNormalizer , item , itemAlreadyIn ) ) { indexCharacters . set ( insertionPoint , item ) ; } } } } // if the result is still too large, cut down to maxLabelCount elements, by removing every nth element final int size = indexCharacters . size ( ) - 1 ; if ( size > maxLabelCount ) { int count = 0 ; int old = - 1 ; for ( Iterator < String > it = indexCharacters . iterator ( ) ; it . hasNext ( ) ; ) { ++ count ; it . next ( ) ; final int bump = count * maxLabelCount / size ; if ( bump == old ) { it . remove ( ) ; } else { old = bump ; } } } return indexCharacters ; }
Determine the best labels to use . This is based on the exemplars but we also process to make sure that they are unique and sort differently and that the overall list is small enough .