Естественное сравнение строк порядка сортировки в Java - каждый встроен? [дубликат]

URI является видом суперкласса URL и УРНЫ. Википедия имеет прекрасная статья о них со ссылками на правильный набор RFCs.

69
задан IAdapter 27 September 2009 в 20:42
поделиться

3 ответа

В java «естественный» порядок, означающий «лексикографический», поэтому в ядре нет реализации, подобной той, которую вы ищете.

Существуют реализации с открытым исходным кодом.

Вот один:

NaturalOrderComparator.java

Убедитесь, что вы прочитали:

Cougaar Open Source License

Надеюсь, это поможет!

51
ответ дан 24 November 2019 в 13:55
поделиться

String реализует Comparable, и это естественный порядок в Java (сравнение с использованием сопоставимого интерфейса). Вы можете поместить строки в TreeSet или отсортировать, используя классы Collections или Arrays.

Однако в вашем случае вам не нужен «естественный порядок», вам действительно нужен настраиваемый компаратор, который затем можно использовать в коллекциях. sort или метод Arrays.sort, который использует компаратор.

Что касается конкретной логики, которую вы ищете для реализации в компараторе (числа, разделенные точками), мне не известны какие-либо существующие стандартные реализации этого, но, как вы сказали, это не сложная проблема.

РЕДАКТИРОВАТЬ: В вашем комментарии ваша ссылка приводит вас сюда , что делает приличную работу, если вы не возражаете против того факта, что это так чувствительный. Вот этот код, измененный, чтобы вы могли передавать String.CASE_INSENSITIVE_ORDER :

    /*
     * The Alphanum Algorithm is an improved sorting algorithm for strings
     * containing numbers.  Instead of sorting numbers in ASCII order like
     * a standard sort, this algorithm sorts numbers in numeric order.
     *
     * The Alphanum Algorithm is discussed at http://www.DaveKoelle.com
     *
     *
     * This library is free software; you can redistribute it and/or
     * modify it under the terms of the GNU Lesser General Public
     * License as published by the Free Software Foundation; either
     * version 2.1 of the License, or any later version.
     *
     * This library is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     * Lesser General Public License for more details.
     *
     * You should have received a copy of the GNU Lesser General Public
     * License along with this library; if not, write to the Free Software
     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     *
     */

    import java.util.Comparator;

    /**
     * This is an updated version with enhancements made by Daniel Migowski,
     * Andre Bogus, and David Koelle
     *
     * To convert to use Templates (Java 1.5+):
     *   - Change "implements Comparator" to "implements Comparator<String>"
     *   - Change "compare(Object o1, Object o2)" to "compare(String s1, String s2)"
     *   - Remove the type checking and casting in compare().
     *
     * To use this class:
     *   Use the static "sort" method from the java.util.Collections class:
     *   Collections.sort(your list, new AlphanumComparator());
     */
    public class AlphanumComparator implements Comparator<String>
    {
        private Comparator<String> comparator = new NaturalComparator();

        public AlphanumComparator(Comparator<String> comparator) {
            this.comparator = comparator;
        }

        public AlphanumComparator() {

        }

        private final boolean isDigit(char ch)
        {
            return ch >= 48 && ch <= 57;
        }

        /** Length of string is passed in for improved efficiency (only need to calculate it once) **/
        private final String getChunk(String s, int slength, int marker)
        {
            StringBuilder chunk = new StringBuilder();
            char c = s.charAt(marker);
            chunk.append(c);
            marker++;
            if (isDigit(c))
            {
                while (marker < slength)
                {
                    c = s.charAt(marker);
                    if (!isDigit(c))
                        break;
                    chunk.append(c);
                    marker++;
                }
            } else
            {
                while (marker < slength)
                {
                    c = s.charAt(marker);
                    if (isDigit(c))
                        break;
                    chunk.append(c);
                    marker++;
                }
            }
            return chunk.toString();
        }

        public int compare(String s1, String s2)
        {

            int thisMarker = 0;
            int thatMarker = 0;
            int s1Length = s1.length();
            int s2Length = s2.length();

            while (thisMarker < s1Length && thatMarker < s2Length)
            {
                String thisChunk = getChunk(s1, s1Length, thisMarker);
                thisMarker += thisChunk.length();

                String thatChunk = getChunk(s2, s2Length, thatMarker);
                thatMarker += thatChunk.length();

                // If both chunks contain numeric characters, sort them numerically
                int result = 0;
                if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0)))
                {
                    // Simple chunk comparison by length.
                    int thisChunkLength = thisChunk.length();
                    result = thisChunkLength - thatChunk.length();
                    // If equal, the first different number counts
                    if (result == 0)
                    {
                        for (int i = 0; i < thisChunkLength; i++)
                        {
                            result = thisChunk.charAt(i) - thatChunk.charAt(i);
                            if (result != 0)
                            {
                                return result;
                            }
                        }
                    }
                } else
                {
                    result = comparator.compare(thisChunk, thatChunk);
                }

                if (result != 0)
                    return result;
            }

            return s1Length - s2Length;
        }

        private static class NaturalComparator implements Comparator<String> {
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        }
    }
8
ответ дан 24 November 2019 в 13:55
поделиться

Я протестировал три реализации Java, упомянутые здесь другими, и обнаружил, что их работа немного отличается, но ни одна из них не соответствует моим ожиданиям.

Оба AlphaNumericStringComparator и AlphanumComparator не игнорируют пробелы, поэтому pic2 помещается перед pic 1 .

С другой стороны, NaturalOrderComparator игнорирует не только пробелы, но и все ведущие нули, так что sig [1] предшествует sig [0] .

. Что касается производительности AlphaNumericStringComparator примерно в 10 раз медленнее, чем два других.

9
ответ дан 24 November 2019 в 13:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: