创造;序数;基于唯一集的Java中基于列表整型元素的聚类

创造;序数;基于唯一集的Java中基于列表整型元素的聚类,java,arraylist,grouping,clustered-index,Java,Arraylist,Grouping,Clustered Index,我正在尝试使用整数列表中的数字从1开始创建有序集群 例如,如果我有一个列表整数,比如:[-1,7,99,4,5,33,6,4,77,3,7,99,2,7],这些数字是由算法返回的集群。该算法不会创建像1、2、3这样的连续编号。。。而是随机“跳跃” 所以我想要实现的或多或少是集群的一个干净版本。唯一的例外是,上述列表中的任何数字为-1,将在新的有序编号集群列表中保持为-1 为了说明这一点,假设在上面的列表中,我创建了一组独特的元素:{-1,2,3,4,5,6,7,33,77,99}对于这些独特的集

我正在尝试使用整数列表中的数字从1开始创建有序集群

例如,如果我有一个列表整数,比如:[-1,7,99,4,5,33,6,4,77,3,7,99,2,7],这些数字是由算法返回的集群。该算法不会创建像1、2、3这样的连续编号。。。而是随机“跳跃”

所以我想要实现的或多或少是集群的一个干净版本。唯一的例外是,上述列表中的任何数字为-1,将在新的有序编号集群列表中保持为-1

为了说明这一点,假设在上面的列表中,我创建了一组独特的元素:{-1,2,3,4,5,6,7,33,77,99}对于这些独特的集群,我想创建新的编号,例如将集合更改为{-1,1,2,3,4,5,6,7,8,9},以替换之前的集合,同时保持-1的完整性。上一个集合中的每个索引对应于新集合中的索引

有了这个新的集合,我想运行列表整数并相应地更新它。所以,对于上面的例子,我会:[-1,6,9,3,4,7,5,3,8,2,6,9,1,6]

到目前为止我做了什么?

import java.util.*;

public class testing {
    public static void main(String[] args) {

    int[] myIntArray = new int[]{-1, 1, 2, 3, 4, 5, 5, -1, 7, 5, 9, 5, 5, 10,
            4, 14, -1, 5, 5, 5, 5, 5, 14, 5, 22, 5, 5, 25, 5, 22, 22, 5, 5, 5, 4, 5, 4, 7, 5, 5, 14, 14, 5,
            5, 22, 9, 2, 5, 22, -1, 47, 5, 5, 5, 5, 5, 4, -1, -1, 5, 5, 22, 5, 5, 5, 9, 5, 5, 5, 5, 65, 5,
            5, 5, 5, 14, 5, 10, 5, -1, 5, 22, 5, 14, 14, 5, 5, 5, 5, 5, 22, 5, 5, 5, 5, 5, -1, -1, 90, 22,
            -1, 92, 47, -1, 65, -1, 47, -1, 5, 1, -1, 7, 47, 92, -1, 9, -1, 9, -1, 103, 47, 3, 14, 107, 1,
            92, -1, 4, -1, 4, 14, -1, 9, -1, -1, 22, -1, 9, 22, 92, 25, 92, 9, 14, -1, 92, 103, 47, 4, -1,
            22, 9, 92, 47, -1, 47, 9, 7, 107, -1, -1, 47, 9, 14, 4, 47, -1, 22, 4, 22, 9, 9, 90, -1, -1, 4,
            4, 22, 22, 103, 47, 47, -1, -1, 9, 14, 9, 4, 4, 22, 22, 159, 9, 103, 4, 22, 4, 159, 90, 4};

    List<Integer> myListInteger = new ArrayList<Integer>(myIntArray.length);

    // passing values to myListInteger from myIntArray
    for (int i : myIntArray) {
        myListInteger.add(i);
    }

    // get distinct numbers in myListInteger: Set
    Set<Integer> distinctNumbersSet = new HashSet<Integer>(myListInteger);

    // convert to List
    List<Integer> distinctIntegerList = new ArrayList<>();
    for (Integer i: distinctNumbersSet) {
        distinctIntegerList.add(i);
    }

    // index to start numbering unique values
    int index = 1;
    boolean increaseIndex = false;


    for (int i = 0; i < distinctIntegerList.size(); i++) {
        for (int j = 0; j < myListInteger.size(); j++ ) {
            if (myListInteger.get(j) == -1) {
                continue;
            }

            if (distinctIntegerList.get(i) == myListInteger.get(j)) {
                myListInteger.set(j, index);
                increaseIndex = true;
                continue;
            }
        }
        if (increaseIndex == true) {
            index++;
            increaseIndex = false;
        }

    }

    // after update the myListInteger, I can get distinct sets again
    Set<Integer> distinctSetAfterUpdate = new HashSet<Integer>(myListInteger);

    System.out.println(myListInteger); // there is a 159 almost at the end, while it is expected that it should be 18

    for (Integer ind: distinctSetAfterUpdate) {
        System.out.println(ind + ": " +  Collections.frequency(myListInteger, ind));
    }



    }
}
当我想

-1: 33
1: 3
2: 2
3: 2
4: 17
5: 56
6: 4
7: 16
8: 2
9: 12
10: 19
11: 2
12: 12
13: 2
14: 3
15: 7
16: 4
17: 2
18: 2

试图理解为什么我的代码没有两次将159映射到18,而只映射到18,有什么帮助吗?

问题出在这一行:

if (distinctIntegerList.get(i) == myListInteger.get(j))
列表中有整数类型。
=
用于比较基本类型(int、long、double..)。 比较引用类型(整数、双精度、长型)时,应始终使用equals方法

把那行改成

if (distinctIntegerList.get(i).equals(myListInteger.get(j)))

最好在任务中使用映射而不是列表,这会使代码更具可读性:

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.stream.Collectors;

public class MainData {

    static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {

        int[] myIntArray = new int[]{-1, 1, 2, 3, 4, 5, 5, -1, 7, 5, 9, 5, 5, 10,
            4, 14, -1, 5, 5, 5, 5, 5, 14, 5, 22, 5, 5, 25, 5, 22, 22, 5, 5, 5, 4, 5, 4, 7, 5, 5, 14, 14, 5,
            5, 22, 9, 2, 5, 22, -1, 47, 5, 5, 5, 5, 5, 4, -1, -1, 5, 5, 22, 5, 5, 5, 9, 5, 5, 5, 5, 65, 5,
            5, 5, 5, 14, 5, 10, 5, -1, 5, 22, 5, 14, 14, 5, 5, 5, 5, 5, 22, 5, 5, 5, 5, 5, -1, -1, 90, 22,
            -1, 92, 47, -1, 65, -1, 47, -1, 5, 1, -1, 7, 47, 92, -1, 9, -1, 9, -1, 103, 47, 3, 14, 107, 1,
            92, -1, 4, -1, 4, 14, -1, 9, -1, -1, 22, -1, 9, 22, 92, 25, 92, 9, 14, -1, 92, 103, 47, 4, -1,
            22, 9, 92, 47, -1, 47, 9, 7, 107, -1, -1, 47, 9, 14, 4, 47, -1, 22, 4, 22, 9, 9, 90, -1, -1, 4,
            4, 22, 22, 103, 47, 47, -1, -1, 9, 14, 9, 4, 4, 22, 22, 159, 9, 103, 4, 22, 4, 159, 90, 4};
        //distinct values of your array collected to list
        List<Integer> myListInteger = Arrays.stream(myIntArray).boxed().distinct().sorted()
                                            .collect(Collectors.toList());

        System.out.println(myListInteger);

        //map your unique values to there index, except -1
        Map<Integer, Integer> indexToUniqueValue = new HashMap<>();
        indexToUniqueValue.put(-1, -1);

        for (int i = 1; i < myListInteger.size(); i++) {
            indexToUniqueValue.put(i, myListInteger.get(i));
        }

        System.out.println(indexToUniqueValue);

        //map the indexes to frequency in your original array
        Map<Integer, Integer> indexToFrequency = new HashMap<>();
        for (Map.Entry<Integer, Integer> entry : indexToUniqueValue.entrySet()) {
            indexToFrequency.put(entry.getKey(), countFreq(entry.getValue(), myIntArray));
        }
        System.out.println(indexToFrequency);
    }

    private static Integer countFreq(Integer value, int[] myIntArray) {
        int count = 0;
        for (int i : myIntArray) {
            if (i == value) {
                count++;
            }
        }
        return count;
    }
}
导入java.util.array;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入java.util.Scanner;
导入java.util.stream.collector;
公共类主数据{
静态扫描仪=新扫描仪(System.in);
公共静态void main(字符串[]args){
int[]myIntArray=新的int[]{-1,1,2,3,4,5,5,-1,7,5,9,5,5,10,
4, 14, -1, 5, 5, 5, 5, 5, 14, 5, 22, 5, 5, 25, 5, 22, 22, 5, 5, 5, 4, 5, 4, 7, 5, 5, 14, 14, 5,
5, 22, 9, 2, 5, 22, -1, 47, 5, 5, 5, 5, 5, 4, -1, -1, 5, 5, 22, 5, 5, 5, 9, 5, 5, 5, 5, 65, 5,
5, 5, 5, 14, 5, 10, 5, -1, 5, 22, 5, 14, 14, 5, 5, 5, 5, 5, 22, 5, 5, 5, 5, 5, -1, -1, 90, 22,
-1, 92, 47, -1, 65, -1, 47, -1, 5, 1, -1, 7, 47, 92, -1, 9, -1, 9, -1, 103, 47, 3, 14, 107, 1,
92, -1, 4, -1, 4, 14, -1, 9, -1, -1, 22, -1, 9, 22, 92, 25, 92, 9, 14, -1, 92, 103, 47, 4, -1,
22, 9, 92, 47, -1, 47, 9, 7, 107, -1, -1, 47, 9, 14, 4, 47, -1, 22, 4, 22, 9, 9, 90, -1, -1, 4,
4, 22, 22, 103, 47, 47, -1, -1, 9, 14, 9, 4, 4, 22, 22, 159, 9, 103, 4, 22, 4, 159, 90, 4};
//收集到列表中的数组的不同值
列出myListInteger=Arrays.stream(myIntArray.boxed().distinct().sorted())
.collect(Collectors.toList());
System.out.println(myListInteger);
//将您的唯一值映射到除-1之外的索引
Map indexToUniqueValue=新HashMap();
指数加权值put(-1,-1);
对于(int i=1;i
好的,这是我的问题。我不明白你到底想做什么。获取唯一值的有序列表很简单,但在这之后,就没有什么意义了。也许你比我更了解你的描述,但是如果你不能清楚地解释这个问题,那么试图编码它将是一团混乱。发生的是,我上面的值列表代表了我问题中的“集群”。但是,由于生成它们的初始代码并不重要,问题是,我希望这些“集群”是“平滑的”,如果您想向某人提出问题并告诉他们存在集群45、90等,那么他们可以问,中间集群在哪里?因为没有,所以我创建了一组唯一的数字,并希望将这组数字替换为从1开始的有序数字,同时忽略列表中的数字-1,即保留它们在新列表中的状态。-1的意思是:未聚集。从
{-1,1,2,3,4,5,6,7,8,9}
=>`[-1,6,9,3,4,7,5,3,8,2,6,9,1,6]`中获取的步骤不清楚。此外,我上面粘贴的输出只是为了可视化新列表上的分布,因此从中我可以看出有一个问题,159原始列表中的元素不应该存在。我不知道如何删除它,因为根据我的代码,它应该落在“集群”18中,因此18有2个元素。@厄立特里亚人,我在示例中显示的基本上是,我想将集合中的数字替换为从1开始的有序数字,除了数字-1,即我保持原样。。。。然后,在做了这些之后,我返回到集合所基于的列表,并用新集合中的新数字替换这些数字…非常感谢。我不知道。我是Java新手:-)也谢谢你的介绍,非常简洁:-)
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.stream.Collectors;

public class MainData {

    static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {

        int[] myIntArray = new int[]{-1, 1, 2, 3, 4, 5, 5, -1, 7, 5, 9, 5, 5, 10,
            4, 14, -1, 5, 5, 5, 5, 5, 14, 5, 22, 5, 5, 25, 5, 22, 22, 5, 5, 5, 4, 5, 4, 7, 5, 5, 14, 14, 5,
            5, 22, 9, 2, 5, 22, -1, 47, 5, 5, 5, 5, 5, 4, -1, -1, 5, 5, 22, 5, 5, 5, 9, 5, 5, 5, 5, 65, 5,
            5, 5, 5, 14, 5, 10, 5, -1, 5, 22, 5, 14, 14, 5, 5, 5, 5, 5, 22, 5, 5, 5, 5, 5, -1, -1, 90, 22,
            -1, 92, 47, -1, 65, -1, 47, -1, 5, 1, -1, 7, 47, 92, -1, 9, -1, 9, -1, 103, 47, 3, 14, 107, 1,
            92, -1, 4, -1, 4, 14, -1, 9, -1, -1, 22, -1, 9, 22, 92, 25, 92, 9, 14, -1, 92, 103, 47, 4, -1,
            22, 9, 92, 47, -1, 47, 9, 7, 107, -1, -1, 47, 9, 14, 4, 47, -1, 22, 4, 22, 9, 9, 90, -1, -1, 4,
            4, 22, 22, 103, 47, 47, -1, -1, 9, 14, 9, 4, 4, 22, 22, 159, 9, 103, 4, 22, 4, 159, 90, 4};
        //distinct values of your array collected to list
        List<Integer> myListInteger = Arrays.stream(myIntArray).boxed().distinct().sorted()
                                            .collect(Collectors.toList());

        System.out.println(myListInteger);

        //map your unique values to there index, except -1
        Map<Integer, Integer> indexToUniqueValue = new HashMap<>();
        indexToUniqueValue.put(-1, -1);

        for (int i = 1; i < myListInteger.size(); i++) {
            indexToUniqueValue.put(i, myListInteger.get(i));
        }

        System.out.println(indexToUniqueValue);

        //map the indexes to frequency in your original array
        Map<Integer, Integer> indexToFrequency = new HashMap<>();
        for (Map.Entry<Integer, Integer> entry : indexToUniqueValue.entrySet()) {
            indexToFrequency.put(entry.getKey(), countFreq(entry.getValue(), myIntArray));
        }
        System.out.println(indexToFrequency);
    }

    private static Integer countFreq(Integer value, int[] myIntArray) {
        int count = 0;
        for (int i : myIntArray) {
            if (i == value) {
                count++;
            }
        }
        return count;
    }
}