使用 HashMap 对 ArrayList 进行字母数字排序
Alphanumeric sorting of ArrayList with HashMap
我有一个 ArrayList
每个索引有几个对象。我想特别按一个对象按字母数字顺序对该列表进行排序。对象是 "my_id",此对象的值类似于:1A、10B、11B、2C、205Z 等。
我需要对这些进行排序才能得出:1A、2C、10B、11B、205Z。首先对数字部分进行排序,然后对字母部分进行次要排序。 1,2,3,4,5,... A,B,C,D,E,...
我检查了一些非常有效的字母数字字符串排序:
http://sanjaal.com/java/206/java-data-structure/alphanumeric-string-sorting-in-java-implementation/
不幸的是,我只能对那个对象进行排序,结果我丢失了 ArrayList
中的其他对象。我真的需要一个排序算法,可以根据我选择的对象重新排列 ArrayList
索引,而不丢失其他对象!
有没有办法做到这一点?我一直找不到。我认为添加 ArrayList
中的所有对象都是映射字符串是很有用的:ArrayList<HashMap<String, String>>
[编辑]
我有我的数组:
ArrayList<HashMap<String, String>> al
然后我存储对象:
String[] alphaNumericStringArray = new String[al.size()];
for(int i = 0; i < al.size(); i++)
{
alphaNumericStringArray[i] = al.get(i).get("my_id");
}
我现在对字符串数组进行排序:
// Sort the array now.
Arrays.sort(alphaNumericStringArray, new AlphanumericSorting());
然后我把对象放回去:
for(int i = 0; i < al.size(); i++)
{
HashMap<String, String> map = new HashMap<String, String>();
map.put("my_id", alphaNumericStringArray[i]);
// TODO, need to append the rest of the objects.
al.set(i, map);
}
我知道你在想什么,我在重新映射时并没有添加所有对象。这就是我目前拥有的,但我想要的是一种对整个列表进行排序的方法,而不仅仅是一个对象 "my_id"。我想重新排列索引,这样我就不必在最后重新映射所有内容。
运行 main
方法:
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Sorter {
public static void main(String[] args) {
List<String> unsorted = Arrays.asList("1A", "10B", "B", "753c", "Z", "M7", "32x", "11B", "2C", "205Z");
Collections.sort(unsorted, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
if (o1.isEmpty())
return -1;
if (o2.isEmpty())
return 1;
String o1number = extractNumberPrefix(o1);
String o2number = extractNumberPrefix(o2);
if (o1number.isEmpty())
if (o2number.isEmpty())
return o1.compareTo(o2);
else return 1;
if (o2number.isEmpty())
return -1;
if (o1number.equals(o2number))
return o1.compareTo(o2);
return Integer.parseInt(o1number) - Integer.parseInt(o2number);
}
private String extractNumberPrefix(String o1) {
String result = "";
for (int i = 0; i < o1.length(); i++) {
try {
Integer.parseInt(o1.substring(i, i + 1));
result += o1.substring(i, i + 1);
} catch (Exception e) {
break;
}
}
return result;
}
});
System.out.println("sorted = " + unsorted);
}
}
returns:
sorted = [1A, 2C, 10B, 11B, 32x, 205Z, 753c, B, M7, Z]
在仔细重建比较器和所有评论之后,我终于想出了如何做到这一点。
问题:
重申我的目标是什么,以及解决方案。我有一个 ArrayList<HashMap<String, String>>
。我想按 HashMap 中的一个对象对 ArrayList 进行排序。我的 HashMap 中有超过 1 个对象,所以我想保留数组的整个索引。我还想按字母数字排序,其中数值是第一个排序的,而不是按字母顺序排序。即 1,2,3,4,... A,B,C,D,...
参考文献:
http://sanjaal.com/java/206/java-data-structure/alphanumeric-string-sorting-in-java-implementation/
TL;DR 解决方案:
在我的自定义比较器函数 public int compare(object firstObj, Object secondObj)
中,我需要将字符串值更改为 HashMap 对象 references/values。这里的 KEY_ID 是我想要排序的对象。完成此操作后,我使用 Collections.sort 按 HashMap 比较器而不是 Arrays.sort 进行排序(集合句柄 ArrayList/HashMaps)。
代码解:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
/**
* DOCUMENTATION:
* http://sanjaal.com/java/206/java-data-structure/alphanumeric-string-sorting-in-java-implementation/
**/
@SuppressWarnings({"rawtypes", "unchecked"})
public class AlphanumericSorting implements Comparator
{
public int compare(Object firstObjToCompare, Object secondObjToCompare)
{
String firstString = ((HashMap<String,String>) firstObjToCompare).get("KEY_ID");
String secondString = ((HashMap<String,String>) secondObjToCompare).get("KEY_ID");
//String firstString = firstObjToCompare.toString();
//String secondString = secondObjToCompare.toString();
if (secondString == null || firstString == null)
{
return 0;
}
int lengthFirstStr = firstString.length();
int lengthSecondStr = secondString.length();
int index1 = 0;
int index2 = 0;
while(index1 < lengthFirstStr && index2 < lengthSecondStr)
{
char ch1 = firstString.charAt(index1);
char ch2 = secondString.charAt(index2);
char[] space1 = new char[lengthFirstStr];
char[] space2 = new char[lengthSecondStr];
int loc1 = 0;
int loc2 = 0;
do
{
space1[loc1++] = ch1;
index1++;
if (index1 < lengthFirstStr)
{
ch1 = firstString.charAt(index1);
}
else
{
break;
}
}
while (Character.isDigit(ch1) == Character.isDigit(space1[0]));
do
{
space2[loc2++] = ch2;
index2++;
if (index2 < lengthSecondStr)
{
ch2 = secondString.charAt(index2);
} else
{
break;
}
}
while (Character.isDigit(ch2) == Character.isDigit(space2[0]));
String str1 = new String(space1);
String str2 = new String(space2);
int result;
if (Character.isDigit(space1[0]) && Character.isDigit(space2[0]))
{
Integer firstNumberToCompare = new Integer(Integer.parseInt(str1.trim()));
Integer secondNumberToCompare = new Integer(Integer.parseInt(str2.trim()));
result = firstNumberToCompare.compareTo(secondNumberToCompare);
}
else
{
result = str1.compareTo(str2);
}
if (result != 0)
{
return result;
}
}
return lengthFirstStr - lengthSecondStr;
}
/**
* ALPHANUMERIC SORTING
*/
public static ArrayList<HashMap<String, String>> sortArrayList(ArrayList<HashMap<String, String>> al)
{
Collections.sort(al, new AlphanumericSorting());
return al;
}
}
到return排序的ArrayList:
myArrayList = AlphanumericSorting.sortArrayList(myArrayList);
其中,
ArrayList<HashMap<String, String>> myArrayList;
我有一个 ArrayList
每个索引有几个对象。我想特别按一个对象按字母数字顺序对该列表进行排序。对象是 "my_id",此对象的值类似于:1A、10B、11B、2C、205Z 等。
我需要对这些进行排序才能得出:1A、2C、10B、11B、205Z。首先对数字部分进行排序,然后对字母部分进行次要排序。 1,2,3,4,5,... A,B,C,D,E,...
我检查了一些非常有效的字母数字字符串排序: http://sanjaal.com/java/206/java-data-structure/alphanumeric-string-sorting-in-java-implementation/
不幸的是,我只能对那个对象进行排序,结果我丢失了 ArrayList
中的其他对象。我真的需要一个排序算法,可以根据我选择的对象重新排列 ArrayList
索引,而不丢失其他对象!
有没有办法做到这一点?我一直找不到。我认为添加 ArrayList
中的所有对象都是映射字符串是很有用的:ArrayList<HashMap<String, String>>
[编辑]
我有我的数组:
ArrayList<HashMap<String, String>> al
然后我存储对象:
String[] alphaNumericStringArray = new String[al.size()];
for(int i = 0; i < al.size(); i++)
{
alphaNumericStringArray[i] = al.get(i).get("my_id");
}
我现在对字符串数组进行排序:
// Sort the array now.
Arrays.sort(alphaNumericStringArray, new AlphanumericSorting());
然后我把对象放回去:
for(int i = 0; i < al.size(); i++)
{
HashMap<String, String> map = new HashMap<String, String>();
map.put("my_id", alphaNumericStringArray[i]);
// TODO, need to append the rest of the objects.
al.set(i, map);
}
我知道你在想什么,我在重新映射时并没有添加所有对象。这就是我目前拥有的,但我想要的是一种对整个列表进行排序的方法,而不仅仅是一个对象 "my_id"。我想重新排列索引,这样我就不必在最后重新映射所有内容。
运行 main
方法:
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Sorter {
public static void main(String[] args) {
List<String> unsorted = Arrays.asList("1A", "10B", "B", "753c", "Z", "M7", "32x", "11B", "2C", "205Z");
Collections.sort(unsorted, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
if (o1.isEmpty())
return -1;
if (o2.isEmpty())
return 1;
String o1number = extractNumberPrefix(o1);
String o2number = extractNumberPrefix(o2);
if (o1number.isEmpty())
if (o2number.isEmpty())
return o1.compareTo(o2);
else return 1;
if (o2number.isEmpty())
return -1;
if (o1number.equals(o2number))
return o1.compareTo(o2);
return Integer.parseInt(o1number) - Integer.parseInt(o2number);
}
private String extractNumberPrefix(String o1) {
String result = "";
for (int i = 0; i < o1.length(); i++) {
try {
Integer.parseInt(o1.substring(i, i + 1));
result += o1.substring(i, i + 1);
} catch (Exception e) {
break;
}
}
return result;
}
});
System.out.println("sorted = " + unsorted);
}
}
returns:
sorted = [1A, 2C, 10B, 11B, 32x, 205Z, 753c, B, M7, Z]
在仔细重建比较器和所有评论之后,我终于想出了如何做到这一点。
问题:
重申我的目标是什么,以及解决方案。我有一个 ArrayList<HashMap<String, String>>
。我想按 HashMap 中的一个对象对 ArrayList 进行排序。我的 HashMap 中有超过 1 个对象,所以我想保留数组的整个索引。我还想按字母数字排序,其中数值是第一个排序的,而不是按字母顺序排序。即 1,2,3,4,... A,B,C,D,...
参考文献: http://sanjaal.com/java/206/java-data-structure/alphanumeric-string-sorting-in-java-implementation/
TL;DR 解决方案:
在我的自定义比较器函数 public int compare(object firstObj, Object secondObj)
中,我需要将字符串值更改为 HashMap 对象 references/values。这里的 KEY_ID 是我想要排序的对象。完成此操作后,我使用 Collections.sort 按 HashMap 比较器而不是 Arrays.sort 进行排序(集合句柄 ArrayList/HashMaps)。
代码解:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
/**
* DOCUMENTATION:
* http://sanjaal.com/java/206/java-data-structure/alphanumeric-string-sorting-in-java-implementation/
**/
@SuppressWarnings({"rawtypes", "unchecked"})
public class AlphanumericSorting implements Comparator
{
public int compare(Object firstObjToCompare, Object secondObjToCompare)
{
String firstString = ((HashMap<String,String>) firstObjToCompare).get("KEY_ID");
String secondString = ((HashMap<String,String>) secondObjToCompare).get("KEY_ID");
//String firstString = firstObjToCompare.toString();
//String secondString = secondObjToCompare.toString();
if (secondString == null || firstString == null)
{
return 0;
}
int lengthFirstStr = firstString.length();
int lengthSecondStr = secondString.length();
int index1 = 0;
int index2 = 0;
while(index1 < lengthFirstStr && index2 < lengthSecondStr)
{
char ch1 = firstString.charAt(index1);
char ch2 = secondString.charAt(index2);
char[] space1 = new char[lengthFirstStr];
char[] space2 = new char[lengthSecondStr];
int loc1 = 0;
int loc2 = 0;
do
{
space1[loc1++] = ch1;
index1++;
if (index1 < lengthFirstStr)
{
ch1 = firstString.charAt(index1);
}
else
{
break;
}
}
while (Character.isDigit(ch1) == Character.isDigit(space1[0]));
do
{
space2[loc2++] = ch2;
index2++;
if (index2 < lengthSecondStr)
{
ch2 = secondString.charAt(index2);
} else
{
break;
}
}
while (Character.isDigit(ch2) == Character.isDigit(space2[0]));
String str1 = new String(space1);
String str2 = new String(space2);
int result;
if (Character.isDigit(space1[0]) && Character.isDigit(space2[0]))
{
Integer firstNumberToCompare = new Integer(Integer.parseInt(str1.trim()));
Integer secondNumberToCompare = new Integer(Integer.parseInt(str2.trim()));
result = firstNumberToCompare.compareTo(secondNumberToCompare);
}
else
{
result = str1.compareTo(str2);
}
if (result != 0)
{
return result;
}
}
return lengthFirstStr - lengthSecondStr;
}
/**
* ALPHANUMERIC SORTING
*/
public static ArrayList<HashMap<String, String>> sortArrayList(ArrayList<HashMap<String, String>> al)
{
Collections.sort(al, new AlphanumericSorting());
return al;
}
}
到return排序的ArrayList:
myArrayList = AlphanumericSorting.sortArrayList(myArrayList);
其中,
ArrayList<HashMap<String, String>> myArrayList;