`
Elvin.Chu
  • 浏览: 15628 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

String,number,String+number的Comparator排序

阅读更多
    这个比较器写的比较好,多种数据形式也能比对排序。
package code;

import java.util.*;

public class IntuitiveStringComparator<T extends CharSequence> implements
		Comparator<T> {
	private T str1, str2;
	private int pos1, pos2, len1, len2;

	public int compare(T s1, T s2) {
		str1 = s1;
		str2 = s2;
		len1 = str1.length();
		len2 = str2.length();
		pos1 = pos2 = 0;

		if (len1 == 0) {
			return len2 == 0 ? 0 : -1;
		} else if (len2 == 0) {
			return 1;
		}

		if (isNumeric(str1.toString()) && isNumeric(str2.toString())) {
			// System.out.println("test ");
			if (Double.parseDouble(str1.toString()) > Double.parseDouble(str2
					.toString())) {
				return 1;
			} else {
				return -1;
			}

		}else {
			while (pos1 < len1 && pos2 < len2) {
				char ch1 = str1.charAt(pos1);
				char ch2 = str2.charAt(pos2);
				int result = 0;

				if (Character.isDigit(ch1)) {
					result = Character.isDigit(ch2) ? compareNumbers() : -1;
				} else if (Character.isLetter(ch1)) {
					result = Character.isLetter(ch2) ? compareOther(true) : 1;
				} else {
					result = Character.isDigit(ch2) ? 1 : Character
							.isLetter(ch2) ? -1 : compareOther(false);
				}

				if (result != 0) {
					return result;
				}
			}

		}

		return len1 - len2;
	}

	private int compareNumbers() {
		int delta = 0;
		int zeroes1 = 0, zeroes2 = 0;
		char ch1 = (char) 0, ch2 = (char) 0;

		// Skip leading zeroes, but keep a count of them.
		while (pos1 < len1 && (ch1 = str1.charAt(pos1++)) == '0') {
			zeroes1++;
		}
		while (pos2 < len2 && (ch2 = str2.charAt(pos2++)) == '0') {
			zeroes2++;
		}

		// If one sequence contains more significant digits than the
		// other, it's a larger number. In case they turn out to have
		// equal lengths, we compare digits at each position; the first
		// unequal pair determines which is the bigger number.
		while (true) {
			boolean noMoreDigits1 = (ch1 == 0) || !Character.isDigit(ch1);
			boolean noMoreDigits2 = (ch2 == 0) || !Character.isDigit(ch2);

			if (noMoreDigits1 && noMoreDigits2) {
				return delta != 0 ? delta : zeroes1 - zeroes2;
			} else if (noMoreDigits1) {
				return -1;
			} else if (noMoreDigits2) {
				return 1;
			} else if (delta == 0 && ch1 != ch2) {
				delta = ch1 - ch2;
			}

			ch1 = pos1 < len1 ? str1.charAt(pos1++) : (char) 0;
			ch2 = pos2 < len2 ? str2.charAt(pos2++) : (char) 0;
		}
	}

	private int compareOther(boolean isLetters) {
		char ch1 = str1.charAt(pos1++);
		char ch2 = str2.charAt(pos2++);

		if (ch1 == ch2) {
			return 0;
		}

		if (isLetters) {
			ch1 = Character.toUpperCase(ch1);
			ch2 = Character.toUpperCase(ch2);
			if (ch1 != ch2) {
				ch1 = Character.toLowerCase(ch1);
				ch2 = Character.toLowerCase(ch2);
			}
		}

		return ch1 - ch2;
	}

	public boolean isNumeric(String str12) {
		// String str12 = str1.toString();
		try {
			double d = Double.parseDouble(str12);
		} catch (NumberFormatException nfe) {
			return false;
		}
		return true;

		// return str12.matches("-?\\d+(\\.\\d+)?"); //match a number with
		// optional '-' and decimal.
	}

	public static void main(String[] args) {
		String[] list = { "foo 03", "foo 00003", "foo 5", "foo 003", "foo~03",
				"foo 10far", "foo 10boo", "2", "0.5", "foo 10", "-20", "1.1", "foo!03",
					 "1.0", "10000", "20", ".7","-40"

		};

		Arrays.sort(list, new IntuitiveStringComparator<String>());
		for (String s : list) {
			System.out.println(s);
		}
	}
}

运行结果如下:
-40
-20
0.5
.7
1.0
1.1
2
20
10000
foo 03
foo 003
foo 00003
foo 5
foo 10
foo 10far
foo 10boo
foo!03
foo~03


即使小数点前没有零也能正常排序。
分享到:
评论

相关推荐

    List数据字段排序不关注数据库,直接排序

    在 Java 中,我们可以利用 `Collections.sort()` 方法结合自定义的 `Comparator` 来实现对 List 集合的排序。具体做法是创建一个实现了 `Comparator` 接口的类,并在 `compare()` 方法中定义具体的排序逻辑。这里的...

    ArraySort排序

    值得注意的是,如果同时实现了`Comparable`接口的类还需要用`Comparator`进行排序,那么在`Arrays.sort()`方法中传递的`Comparator`会覆盖类的自然排序。 在处理大数据集时,Java还提供了`java.util.Collections....

    java课程设计--个人电话簿(增删查改排序等)

    public Contact(String name, String phoneNumber, String email) { this.name = name; this.phoneNumber = phoneNumber; this.email = email; } // Getter and Setter methods... } ``` 接下来,我们需要一...

    联系人排序功能的实现

    private String phoneNumber; // 构造函数、getter和setter省略 @Override public int compareTo(Contact other) { // 在这里定义默认的排序规则,比如按照姓名升序 return this.name.compareTo(other.name)...

    Java-programs.rar_At Random

    Collections.sort(complexNumbers, new Comparator&lt;ComplexNumber&gt;() { @Override public int compare(ComplexNumber c1, ComplexNumber c2) { if (c1.real != c2.real) { return Double.compare(c1.real, c2....

    JavaSE练习题.docx

    Number number = new Number(10, 5); System.out.println("Addition: " + number.addition()); System.out.println("Subtraction: " + number.subtraction()); System.out.println("Multiplication: " + number....

    492.490.JAVA基础教程_常用类-自定义类实现Comparable自然排序(492).rar

    当一个类实现了`Comparable`接口后,其对象可以在使用了`Comparator`接口的集合类(如`TreeSet`或`TreeMap`)中自动进行自然排序。这意味着集合中的对象会按照`compareTo`方法定义的顺序进行排列。 **自定义类与...

    alphanum:使用 DaveKoelle.com 的 Alphanum 算法进行自然排序

    public class AlphanumComparator implements Comparator&lt;String&gt; { @Override public int compare(String s1, String s2) { int index1 = 0, index2 = 0; while (index1 () && index2 ()) { if (isNumeric(s1,...

    在Typescript上编写有用的比较器函数

    type Comparator&lt;T&gt; = (a: T, b: T) =&gt; number; ``` 二、自定义比较器 1. 字符串比较:当你需要按特定规则(如字母顺序或大小写敏感/不敏感)排序字符串时,可以创建自定义的比较器函数。例如,以下是一个忽略大小...

    JAVA面试笔试题

    在Java中,为了方便对自定义对象进行排序,可以使用`Comparable`接口或`Comparator`接口。这里以`Comparator`为例进行说明。 假设有一个`Student`类,包含`name`、`code`、`age`和`agent`属性,要按`age`进行排序,...

    浅谈Java之Map 按值排序 (Map sort by value)

    在这个例子中,我们可以创建一个名为Pair的类,包含一个String类型的键(name)和一个int类型的值(number)。Pair类需要重写compareTo()方法,使得比较时依据值(number)进行排序。在主程序中,我们可以创建一个...

    精选笔试机试题Java

    public String largestNumber(int[] nums) { String res = ""; if (nums == null || nums.length == 0) { return res; } // 将所有数字转换为字符串 String[] strNums = new String[nums.length]; for (int ...

    java上机题目小总结.docx

    - 使用`Collections.sort()`方法对`ArrayList`进行排序,需定义比较器来实现按成绩排序。 3. **输出:** - 遍历排序后的`ArrayList`,输出每个学生的姓名和成绩。 **示例代码框架:** ```java import java.util....

    .archjava机试题11.docx

    public static void recharge(String cardNumber, double amount) { for (MemberCard card : cards) { if (card.getCardNumber().equals(cardNumber)) { card.setBalance(card.getBalance() + amount); break; ...

    Java笔记word.docx

    在比较列表中的元素大小时,可以使用`Collections.sort()`方法对列表进行排序,也可以通过`Comparator`接口自定义比较逻辑。 **示例**: ```java List&lt;Integer&gt; list = Arrays.asList(3, 1, 4, 1, 5); Collections...

    泛型+泛型类+定义和使用+理解

    例如,ArrayList&lt;String&gt; 就是一个泛型实例,它只能存储String类型的数据。 **泛型类** 是包含类型参数的类。定义泛型类的语法如下: ```java public class MyClass&lt;T&gt; { private T data; public MyClass(T ...

    最全的java面试题

    - 使用`String.valueOf(number)`方法。 ##### 25. 如何去小数点前两位,并四舍五入。 - 使用`Math.round()`或`DecimalFormat`类。 ##### 26. 如何取得年月日,小时分秒? - 使用`LocalDateTime`类。 #### 九、...

    Java泛型深入研究

    而`Comparator&lt;Number&gt;`不是`Comparator&lt;Object&gt;`的子类型,但`Comparator&lt;Object&gt;`是`Comparator&lt;Number&gt;`的子类型,这是逆变。 6. **类型推断**:Java 7引入的钻石操作符`&lt;&gt;`简化了泛型实例化,编译器会自动推断...

Global site tag (gtag.js) - Google Analytics