我试图获取具有唯一int []的独特列表,但我仍在重复。
Microsoft.Office.Interop.Excel._Application app = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel._Workbook workbook = app.Workbooks.Add(Type.Missing);
Microsoft.Office.Interop.Excel._Worksheet worksheet = null;
worksheet = workbook.Sheets["Sheet1"];
worksheet = workbook.ActiveSheet;
worksheet.Name = "Exported from gridview";
for (int i = 1; i < dataGridView1.Columns.Count + 1; i++)
{
worksheet.Cells[1, i] = dataGridView1.Columns[i - 1].HeaderText;
}
for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
{
for (int j = 0; j < dataGridView1.Columns.Count; j++)
{
worksheet.Cells[i + 2, j + 1] = dataGridView1.Rows[i].Cells[j].Value.ToString();
}
}
var saveFileDialoge = new SaveFileDialog();
saveFileDialoge.FileName = "output";
saveFileDialoge.DefaultExt = ".xlsx";
if (saveFileDialoge.ShowDialog() == DialogResult.OK)
{
workbook.SaveAs(saveFileDialoge.FileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
app.Visible = true;
从int []的组合列表中获取所需元素的逻辑是数组中的数字应连续且相差1。
例如:{2,3,4}
但是在我的最终列表中,{2,3,4}即将出现3次了,这是显而易见的。我想对{2,3,4}进行1次3次的出现。所以我写了以下逻辑。仍然有许多元素以{4,5,6}的连续形式出现,我希望它们也只被计数一次。
List<Integer> set1 = Arrays.asList(2, 3, 4, 5, 10, 4, 5, 6, 4);
List<Integer> count = new ArrayList<>();
List<int[]> combination = set1.stream().flatMap(i -> set1.stream().
flatMap(j -> set1.stream().map(k -> new int[] { i, j, k })))
.distinct().collect(Collectors.toList());
我得到的唯一元素为15,但应该为3。
我的最终
List<int[]> combination1 = combination.stream().distinct().collect(Collectors.toList()); combination1.stream().filter(i -> Collections.frequency(combination, i) == 1).forEach(s -> { if (s[1] - s[0] == 1 && s[2] - s[1] == 1 && s[2] - s[0] == 2) { count.add(1); } else { count.add(0); } }); System.out.println(count.stream().mapToInt(Integer::intValue).sum());
应该只包含:{2,3,4},{3,4,5},{4,5,6} 因此计数应该为三。
答案 0 :(得分:3)
这是distinct()
文档的第一行:
返回由该流的不同元素(根据
Object.equals(Object)
组成)的流。
现在,因为您正在Stream<int[]>
上运行它,所以当两个int数组具有相同的内容时,int[].equals
将必须返回true
。但事实并非如此(请参阅this)。您可以通过在distinct()
之前使用列表,然后在之后进行映射来解决此问题(此处使用Integer[]
,但是int[]
需要一个不同的映射):
List<Integer[]> combination = set1.stream()
.flatMap(i -> set1.stream()
.flatMap(j -> set1.stream().map(k -> Arrays.asList(i, j, k))))
.distinct()
.map(l -> l.toArray(new Integer[0]))
.collect(Collectors.toList());
答案 1 :(得分:3)
尽管@ernest_k提到了解决方案的基本问题,但我认为您可以通过简单的方式来解决。
首先从set1
个元素创建地图。
Map<Integer,Integer> map = set1.stream()
.collect(Collectors
.toMap(Function.identity(),Function.identity(),(v1,v2)->v1));
{2 = 2,3 = 3,4 = 4,5 = 5,6 = 6,10 = 10}
然后通过循环映射值可以创建连续的数组。
List<Integer[]> combination = map.values()
.stream()
.filter(item -> map.containsKey(item + 1) && map.containsKey(item + 2))
.map(item -> new Integer[] {item, item + 1, item + 2})
.collect(Collectors.toList());
@Holger评论使用set会更简单。
Set<Integer> set = new HashSet<>(set1);
List<Integer[]> combination = set.stream()
.filter(item -> set.contains(item + 1) && set.contains(item + 2))
.map(item -> new Integer[] {item, item + 1, item + 2})
.collect(Collectors.toList());
答案 2 :(得分:3)
如this answer中所述,2019-06-12 00:00:00
数组不具有int[]
的require相等。但是,IntBuffer
可以包装distinct()
数组并提供基于值的相等性。因此,您可以使用序列int[]
获得不同的数组,以包装数组,消除重复并拆开数组。
但是,该问题是完全不必要的步骤的一部分,因为您没有专注于要解决的实际问题。
要获取所有具有连续值的元组,只需使用
map(IntBuffer::wrap).distinct().map(IntBuffer::array)
不是创建所有值的729个组合,而是消除冗余组合,然后消除不匹配的组合,它首先只生成四个可能的升序组合。然后,将其过滤掉,只接受连续数字的序列。
因此最后一条语句将打印
List<Integer> set1 = Arrays.asList(2, 3, 4, 5, 10, 4, 5, 6, 4);
int[] ascending = set1.stream().mapToInt(Integer::intValue).sorted().distinct().toArray();
List<int[]> combination = IntStream.rangeClosed(0, ascending.length - 3)
.mapToObj(ix -> Arrays.copyOfRange(ascending, ix, ix + 3))
.filter(a -> a[0] + 1 == a[1] && a[1] + 1 == a[2])
.collect(Collectors.toList());
combination.forEach(a -> System.out.println(Arrays.toString(a)));