In reality, we will encounter such a situation, the data from the backend server is a one dimensional array, but we display when it’s classification (such as: classification by month to display list), and this time you need to put a one-dimensional array into a two dimensional array, convenient us to display the data. If you rewrite the method details of the transformation every time, you’ll waste a lot of time on repetitive code.
In order to save time, I spent half a day writing out the following utility class to facilitate data conversion to the required format, while sorting the data.
Here’s the code:
1. Compile a helper class for List, Set, Map conversions (CollectionUtils)
public class CollectionUtils {
/** * List set **@param list
* @param <T>
* @return* /
public static <T> Set<T> getSetByList(List<T> list) {
Set<T> result = new HashSet<>(list);
return result;
}
/** * set to list **@param setArrs
* @param <T>
* @return* /
public static <T> List<T> getListBySet(Set<T> setArrs) {
ArrayList<T> result = new ArrayList<T>(setArrs);
return result;
}
/** * map to list, not sort **@param map
* @param <K>
* @param <V>
* @return* /
public static <K, V> List<V> getListByMap(Map<K, V> map) {
return getListByMap(map, null);
}
/** * map to list@param map
* @param <K>
* @param <V>
* @return* /
public static <K, V> List<V> getListByMap(Map<K, V> map, Comparator<V> comparator) {
ArrayList<V> result = new ArrayList<V>();
for (V value : map.values()) {
result.add(value);
}
if(comparator ! =null) {
// Sort
Collections.sort(result, comparator);
}
return result;
}
/** * the list is converted to a map. The key is Integer@param list
* @param <V>
* @return* /
public static <V> Map<Integer, V> getMapByList(List<V> list) {
return getMapByList(list, null);
}
/** * list is converted to map. The key is Integer and the sort is **@param list
* @param <V>
* @return* /
public static <V> Map<Integer, V> getMapByList(List<V> list, Comparator<V> comparator) {
if(comparator ! =null) {
// Sort
Collections.sort(list, comparator);
}
if(list ! =null && list.size() > 0) {
Map<Integer, V> result = new HashMap<>();
for (int i = 0; i < list.size(); i++) {
result.put(i, list.get(i));
}
return result;
}
return null; }}Copy the code
2. Write a static helper classes (AbsTwoDimensionalArrayUtils)
public abstract class AbsTwoDimensionalArrayUtils<K.V> {
// ascending order (from small to large)
public static final int ASC_TYPE = 0;
// Descending order (from large to small)
public static final int DESC_TYPE = 1;
protected Class<K> kClass;
public AbsTwoDimensionalArrayUtils(Class<K> kClass) {
this.kClass = kClass;
}
/** * get the sorted two-dimensional array **@param dataArrays
* @return* /
public List<List<V>> getTwoDimensionalArrayByList(List<V> dataArrays) {
Map<K, List<V>> mapByList = getMapByList(dataArrays);
List<List<V>> result = null;
// Sort the group order
Comparator<Map.Entry<K, List<V>>> keyComparator = getKeyListComparator();
if(keyComparator ! =null) {
result = new ArrayList<>();
List<Map.Entry<K, List<V>>> list = new ArrayList<Map.Entry<K, List<V>>>(mapByList.entrySet());
Collections.sort(list, keyComparator);
for (int i = 0; i < list.size(); i++) {
result.add(list.get(i).getValue());
}
System.out.println("end time " + System.currentTimeMillis());
} else {
// Direct conversion
result = CollectionUtils.getListByMap(mapByList);
}
return result;
}
/** * get HashMap **@param dataArrays
* @return* /
public Map<K, List<V>> getMapByList(List<V> dataArrays) {
System.out.println("start time " + System.currentTimeMillis());
HashMap<K, List<V>> result = new HashMap<K, List<V>>();
if(dataArrays ! =null && dataArrays.size() > 0) {
K key;
for (int i = 0; i < dataArrays.size(); i++) {
V v = dataArrays.get(i);
key = getKey(v);
List<V> value;
if (result.containsKey(key)) {
// If you already have one, take it out
value = result.get(key);
value.add(v);
} else {
value = newArrayList<>(); value.add(v); } result.put(key, value); }}// Sort the data in each group
Comparator<V> valuecomparator = getValueListComparator();
if(valuecomparator ! =null) {
List<V> mapListValue;
for (Map.Entry<K, List<V>> entry : result.entrySet()) {
mapListValue = entry.getValue();
if(mapListValue ! =null && mapListValue.size() > 0) {
Collections.sort(mapListValue, valuecomparator);
}
}
}
System.out.println("end time " + System.currentTimeMillis());
return result;
}
/** * use V to group **@param v
* @return* /
public abstract K getKey(V v);
/** * write the sort of key *@return* /
public abstract Comparator<Map.Entry<K, List<V>>> getKeyListComparator();
/** * write a collation for value **@return* /
public abstract Comparator<V> getValueListComparator(a);
}
Copy the code
3. Write a static help class whose key is int and String
A. when the key is Int, can use AbsIntTwoDimensionalArrayUtils array operations.
public abstract class AbsIntTwoDimensionalArrayUtils<V> extends AbsTwoDimensionalArrayUtils<Integer.V> {
protected Class<V> vClass;
protected Field field;
protected Method method;
protected Field sortField;
protected Method sortMethod;
public AbsIntTwoDimensionalArrayUtils(Class vClass) {
super(Integer.class);
this.vClass = vClass;
String mapName = getMapKeyName();
String sortName = getSortName();
// Get the category field
try {
field = vClass.getField(mapName);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
// Get the sort field
try {
sortField = vClass.getField(sortName);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
// Get the value of the classified field
try {
String firstLetter = mapName.substring(0.1).toUpperCase();
String getter = "get" + firstLetter + mapName.substring(1);
method = vClass.getMethod(getter, new Class[]{});
} catch (Exception e) {
e.printStackTrace();
}
// Get the value of the sorted field
try {
String firstLetterSort = sortName.substring(0.1).toUpperCase();
String getter = "get" + firstLetterSort + sortName.substring(1);
sortMethod = vClass.getMethod(getter, new Class[]{});
} catch(Exception e) { e.printStackTrace(); }}@Override
public Integer getKey(V v) {
if (field == null) {
// The field is not public
try {
return (Integer) method.invoke(v, new Integer[]{});
} catch(Exception ex) { ex.printStackTrace(); }}else {
try {
return field.getInt(v);
} catch(Exception e) { e.printStackTrace(); }}return 0;
}
@Override
public Comparator<Map.Entry<Integer, List<V>>> getKeyListComparator() {
return new Comparator<Map.Entry<Integer, List<V>>>() {
@Override
public int compare(Map.Entry<Integer, List<V>> o1, Map.Entry<Integer, List<V>> o2) {
if (getMapKeySortType() == ASC_TYPE) {
return ascMapKey(o1, o2);
} else {
returndescMapkey(o1, o2); }}}; }/** * Sort by map key in descending order **@param o1
* @param o2
* @return* /
private Integer descMapkey(Map.Entry<Integer, List<V>> o1, Map.Entry<Integer, List<V>> o2) {
try {
if (o1.getKey() > o2.getKey()) {
return -1;
}
if (o1.getKey() < o2.getKey()) {
return 1; }}catch (Exception e) {
e.printStackTrace();
}
return 0;
}
/** * Sort the map by ascending key **@param o1
* @param o2
* @return* /
private Integer ascMapKey(Map.Entry<Integer, List<V>> o1, Map.Entry<Integer, List<V>> o2) {
try {
if (o1.getKey() < o2.getKey()) {
return -1;
}
if (o1.getKey() > o2.getKey()) {
return 1; }}catch (Exception e) {
e.printStackTrace();
}
return 0;
}
@Override
public Comparator<V> getValueListComparator(a) {
return new Comparator<V>() {
@Override
public int compare(V o1, V o2) {
if (getSortType() == ASC_TYPE) {
return sortAsc(o1, o2);
} else {
returnsortDesc(o1, o2); }}}; }/** * sort each child object ** in descending order@param o1
* @param o2
* @return* /
private int sortDesc(V o1, V o2) {
if (sortField == null) {
try {
if (isIntSortFiled()) {
return ((Integer) sortMethod.invoke(o2, new Integer[]{})).compareTo((Integer) sortMethod.invoke(o1, new Integer[]{}));
} else {
return ((String) sortMethod.invoke(o2, new String[]{})).compareTo((String) sortMethod.invoke(o1, newString[]{})); }}catch (IllegalAccessException e) {
e.printStackTrace();
} catch(InvocationTargetException e) { e.printStackTrace(); }}else {
try {
if (isIntSortFiled()) {
if (sortField.getInt(o1) > sortField.getInt(o2)) {
return -1;
}
if (sortField.getInt(o1) < sortField.getInt(o2)) {
return 1; }}else {
return((String) sortField.get(o2)).compareTo((String) sortField.get(o1)); }}catch(Exception e) { e.printStackTrace(); }}return 0;
}
/** * sort each child object in ascending order **@param o1
* @param o2
* @return* /
private int sortAsc(V o1, V o2) {
if (sortField == null) {
try {
if (isIntSortFiled()) {
return ((Integer) sortMethod.invoke(o1, new Integer[]{})).compareTo((Integer) sortMethod.invoke(o2, new Integer[]{}));
} else {
return ((String) sortMethod.invoke(o1, new String[]{})).compareTo((String) sortMethod.invoke(o2, newString[]{})); }}catch (IllegalAccessException e) {
e.printStackTrace();
} catch(InvocationTargetException e) { e.printStackTrace(); }}else {
try {
if (isIntSortFiled()) {
if (sortField.getInt(o1) > sortField.getInt(o2)) {
return 1;
}
if (sortField.getInt(o1) < sortField.getInt(o2)) {
return -1; }}else {
return((String) sortField.get(o1)).compareTo((String) sortField.get(o2)); }}catch(Exception e) { e.printStackTrace(); }}return 0;
}
/** * gets the sort field name of the object **@return* /
public abstract String getSortName(a);
/** * Get the map key field name **@return* /
public abstract String getMapKeyName(a);
/** * Gets how each object is sorted (ascending/descending) **@return* /
public abstract int getSortType(a);
/** * How to sort the map keys (ascending/descending) **@return* /
public abstract int getMapKeySortType(a);
/** * Is the sort field ** of type int@return* /
public abstract boolean isIntSortFiled(a);
}
Copy the code
B. when the key is a String, use AbsStringTwoDimensionalArrayUtils array operations.
public abstract class AbsStringTwoDimensionalArrayUtils<V> extends AbsTwoDimensionalArrayUtils<String.V> {
protected Class<V> vClass;
protected Field field;
protected Method method;
protected Field sortField;
protected Method sortMethod;
public AbsStringTwoDimensionalArrayUtils(Class vClass) {
super(String.class);
this.vClass = vClass;
String mapName = getMapKeyName();
String sortName = getSortName();
// Get the category field
try {
field = vClass.getField(mapName);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
// Get the sort field
try {
sortField = vClass.getField(sortName);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
// Get the value of the classified field
try {
String firstLetter = mapName.substring(0.1).toUpperCase();
String getter = "get" + firstLetter + mapName.substring(1);
method = vClass.getMethod(getter, new Class[]{});
} catch (Exception e) {
e.printStackTrace();
}
// Get the value of the sorted field
try {
String firstLetterSort = sortName.substring(0.1).toUpperCase();
String getter = "get" + firstLetterSort + sortName.substring(1);
sortMethod = vClass.getMethod(getter, new Class[]{});
} catch(Exception e) { e.printStackTrace(); }}@Override
public String getKey(V v) {
if (field == null) {
// The field is not public
try {
return (String) method.invoke(v, new String[]{});
} catch(Exception ex) { ex.printStackTrace(); }}else {
try {
return (String) field.get(v);
} catch(Exception e) { e.printStackTrace(); }}return "";
}
@Override
public Comparator<Map.Entry<String, List<V>>> getKeyListComparator() {
return new Comparator<Map.Entry<String, List<V>>>() {
@Override
public int compare(Map.Entry<String, List<V>> o1, Map.Entry<String, List<V>> o2) {
if (getMapKeySortType() == ASC_TYPE) {
return ascMapKey(o1, o2);
} else {
returndescMapkey(o1, o2); }}}; }/** * Sort by map key in descending order **@param o1
* @param o2
* @return* /
private Integer descMapkey(Map.Entry<String, List<V>> o1, Map.Entry<String, List<V>> o2) {
try {
return o2.getKey().compareTo(o1.getKey());
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
/** * Sort the map by ascending key **@param o1
* @param o2
* @return* /
private Integer ascMapKey(Map.Entry<String, List<V>> o1, Map.Entry<String, List<V>> o2) {
try {
return o1.getKey().compareTo(o2.getKey());
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
@Override
public Comparator<V> getValueListComparator(a) {
return new Comparator<V>() {
@Override
public int compare(V o1, V o2) {
if (getSortType() == ASC_TYPE) {
return sortAsc(o1, o2);
} else {
returnsortDesc(o1, o2); }}}; }/** * sort each child object ** in descending order@param o1
* @param o2
* @return* /
private int sortDesc(V o1, V o2) {
if (sortField == null) {
try {
if (isIntSortFiled()) {
return ((Integer) sortMethod.invoke(o2, new Integer[]{})).compareTo((Integer) sortMethod.invoke(o1, new Integer[]{}));
} else {
return ((String) sortMethod.invoke(o2, new String[]{})).compareTo((String) sortMethod.invoke(o1, newString[]{})); }}catch (IllegalAccessException e) {
e.printStackTrace();
} catch(InvocationTargetException e) { e.printStackTrace(); }}else {
try {
if (isIntSortFiled()) {
if (sortField.getInt(o1) > sortField.getInt(o2)) {
return -1;
}
if (sortField.getInt(o1) < sortField.getInt(o2)) {
return 1; }}else {
return((String) sortField.get(o2)).compareTo((String) sortField.get(o1)); }}catch(Exception e) { e.printStackTrace(); }}return 0;
}
/** * sort each child object in ascending order **@param o1
* @param o2
* @return* /
private int sortAsc(V o1, V o2) {
if (sortField == null) {
try {
if (isIntSortFiled()) {
return ((Integer) sortMethod.invoke(o1, new Integer[]{})).compareTo((Integer) sortMethod.invoke(o2, new Integer[]{}));
} else {
return ((String) sortMethod.invoke(o1, new String[]{})).compareTo((String) sortMethod.invoke(o2, newString[]{})); }}catch (IllegalAccessException e) {
e.printStackTrace();
} catch(InvocationTargetException e) { e.printStackTrace(); }}else {
try {
if (isIntSortFiled()) {
if (sortField.getInt(o1) > sortField.getInt(o2)) {
return 1;
}
if (sortField.getInt(o1) < sortField.getInt(o2)) {
return -1; }}else {
return((String) sortField.get(o1)).compareTo((String) sortField.get(o2)); }}catch(Exception e) { e.printStackTrace(); }}return 0;
}
/** * gets the sort field name of the object **@return* /
public abstract String getSortName(a);
/** * Get the map key field name **@return* /
public abstract String getMapKeyName(a);
/** * Gets how each object is sorted (ascending/descending) **@return* /
public abstract int getSortType(a);
/** * How to sort the map keys (ascending/descending) **@return* /
public abstract int getMapKeySortType(a);
/** * Is the sort field ** of type int@return* /
public abstract boolean isIntSortFiled(a);
}
Copy the code
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — gorgeous line — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
Here’s how to use it:
1. According to the actual data type, to define the helper classes, if the key is Int, inherit AbsIntTwoDimensionalArrayUtils; If the key is a String, will inherit AbsStringTwoDimensionalArrayUtils.
The following example uses an int:
public class TwoDimensionalArrayDemoUtils
extends AbsIntTwoDimensionalArrayUtils<User> {
public TwoDimensionalArrayDemoUtils(a) {
super(User.class);
}
@Override
public String getSortName(a) {
return "name";
}
@Override
public int getSortType(a) {
return ASC_TYPE;
}
@Override
public int getMapKeySortType(a) {
return ASC_TYPE;
}
@Override
public String getMapKeyName(a) {
return "age";
}
@Override
public boolean isIntSortFiled(a) {
return false; }}Copy the code
2. The data type User is as follows:
public class User {
public int id;
private int age;
public String name = "";
public User(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
public int getAge(a) {
return age;
}
public int getId(a) {
return id;
}
public String getName(a) {
returnname; }}Copy the code
3. Call method
TwoDimensionalIntArrayDemoUtils hashMapUtils = new TwoDimensionalIntArrayDemoUtils();
// Get a two-dimensional array
List<List<User>> lists = hashMapUtils.getTwoDimensionalArrayByList(users);
/ / get a HashMap
Map<Integer, List<User>> mapByList = hashMapUtils.getMapByList(users);
Copy the code
By doing this, we can convert a one-dimensional array into a two-dimensional array or a Map and sort the data. This way, we don’t have to rewrite the transformation method at development time, just pass in the data and return the result we want.