我有两个数组:
First array:
25, 20, 50, 30, 12, 11...
Second Array:
New York, New Jersey, Detroit, Atlanta, Chicago, Los Angeles
第二个数组中的每两个城市对应于第一个数据中的一个值。
示例:纽约和新泽西将对应25,底特律和亚特兰大将对应20,依此类推。
我想按降序(50,30,25,20 ......)重新排序第一个数组的数字,但我还希望第二个数组的城市相应地移动,以便它们之前具有相同的值排序之后。
我如何完成这项任务? (我可以使用ArrayList或Array,无论哪个更简单)
答案 0 :(得分:1)
您可以使用TreeMap:
Map<Integer, String[]> map = new TreeMap<>();
for(int i=0;i<firstArray.length;i++){
map.put(firstArray[i], new String[]{secondArray[i * 2], secondArray[i*2+1]});
}
此地图将按自然顺序排序。
但我建议你做容器类。类似的东西:
public class CityPair{
public int value;
public String[] cities = new String[2];
}
现在您可以按数据填写列表:
...
ArrayList list = new ArrayList<CityPair>();
for(int i=0; i<firstArray.length; i++){
CityPair pair = new CityPair();
pair.value = firstArray[i];
pair.cities[0] = secondArray[i*2];
pair.cities[1] = secondArray[i*2+1];
list.add(pair);
}
...
如您所见,我没有检查索引是否超出范围&#34;但您应该这样做。之后,您可以对列表进行排序。您可以使用例如Bubble sort算法手动执行此操作,但更好的方法是编写自定义比较器:
public class CityPairComparator implements Comparator<CityPair> {
@Override
public int compare(CityPair pair1, CityPair pair2) {
return Integer.compare(pair1.value, pair2.value);
}
}
现在,您可以使用Collections实用程序类对列表进行排序:
Collections.sort(list, new CityPairComparator());
使用此approch,您可以替换String[] cities
类CityPair
中的ArrayList<Sting> cities
。然后,它可以为每个值添加两个以上的城市。
答案 1 :(得分:0)
这是一个(4行)解决方案,它也处理不匹配的数组长度:
int[] numbers = {25, 20, 50};
String[] cities = {"New York", "New Jersey", "Detroit", "Atlanta", "Chicago", "Los Angeles"};
Map<Object, Object> map = new TreeMap<>(Comparator.comparing(Integer.class::cast, Integer::compare).reversed());
for (Iterator<?> n = Arrays.stream(numbers).iterator(),
s = Arrays.stream(String.join(",", cities).split(",(?=(([^,]*,){2})*[^,]*,[^,]*$)")).iterator();
n.hasNext() && s.hasNext(); )
map.put(n.next(), s.next());
numbers = map.keySet().stream().map(String::valueOf).mapToInt(Integer::parseInt).toArray();
cities = map.values().stream().map(String::valueOf).map(s -> s.split(",")).flatMap(Arrays::stream).toArray(String[]::new);
这将从每个数组的流中动态创建两个迭代器,两者都键入Object
以允许for循环内的双初始化。 cities数组首先连接成一个字符串,然后拆分成pair-as-a-String(使用适当的正则表达式)。两个迭代器的元素都填充TreeMap
,它有一个反向的Integer
比较器。
由于TreeMaps
以排序顺序进行迭代,因此可以使用keySet()
和values()
的流来生成结果数组。
for
循环的终端条件检查两个迭代器以查看是否有可用的下一个元素,如果数组的长度不相等,则会导致忽略较长数组的多余元素。
答案 2 :(得分:0)
我尝试过这样的解决方案,根据您的要求使用Arraylist:
首先,我为您的操作创建了一个新的数据结构。由于每个值将包含两个城市名称:
public class Citizen implements Comparable<Citizen> {
private int citizenId;
private String subjectOne;
private String subjectTwo;
public Citizen(int rollNumber, String subjectOne, String subjectTwo){
this.citizenId = rollNumber;
this.subjectOne = subjectOne;
this.subjectTwo = subjectTwo;
}
public int getRollNumber() {
return citizenId;
}
public void setRollNumber(int rollNumber) {
this.citizenId = rollNumber;
}
public String getSubjectOne() {
return subjectOne;
}
public void setSubjectOne(String subjectOne) {
this.subjectOne = subjectOne;
}
public String getSubjectTwo() {
return subjectTwo;
}
public void setSubjectTwo(String subjectTwo) {
this.subjectTwo = subjectTwo;
}
public int compareTo(Citizen comparestu) {
int compareage=((Citizen)comparestu).getRollNumber();
/* For Ascending order*/
return this.citizenId-compareage;
/* For Descending order do like this */
//return compareage-this.studentage;
}
@Override
public String toString() {
return "[ rollno=" + citizenId + ", subjectOne=" + subjectOne + ", subjectTwo=" + subjectTwo + "]";
}
}
正如您在此处所见,使用Comparable接口的实现将用于比较的参数视为citizenID。
现在致电:
public static void main(String[] args) {
ArrayList<Citizen> studentList = new ArrayList<Citizen>();
studentList.add(new Citizen(25, "New York", "New Jersey"));
studentList.add(new Citizen(20, "Detroit", "Atlanta"));
studentList.add(new Citizen(50, "Chicago", "Los Angeles"));
studentList.add(new Citizen(30, "Kolkata", "Delhi"));
studentList.add(new Citizen(12, "Munmbai", "Baranasi"));
studentList.add(new Citizen(11, "Bangalore", "Goa"));
Collections.sort(studentList);
for(Citizen student: studentList){
System.out.println(student);
}
}
输出:
[ rollno=11, subjectOne=Bangalore, subjectTwo=Goa]
[ rollno=12, subjectOne=Munmbai, subjectTwo=Baranasi]
[ rollno=20, subjectOne=Detroit, subjectTwo=Atlanta]
[ rollno=25, subjectOne=New York, subjectTwo=New Jersey]
[ rollno=30, subjectOne=Kolkata, subjectTwo=Delhi]
[ rollno=50, subjectOne=Chicago, subjectTwo=Los Angeles]
答案 3 :(得分:0)
Java 8提供了一种更优雅的方式,无需单独的映射即可完成此操作:
int[] array1;
String[] array2;
array2 = IntStream.range(0, Math.min(array1, array2))
.boxed().sorted(Comparator.comparingInt(i -> array1[i]))
.map(i -> array2[i])
.toArray(array2);
仅需要装箱,因为IntStream
没有自定义sorted
的{{1}}方法。我不确定为什么不。
如果您希望以Comparator
结尾,请使用List
代替.collect(Collectors.toList())
。