给定一个数字列表: { 4, 5, 7, 3, 5, 4, 2, 4 }
所需的输出是: { 7, 3, 2 }
我正在考虑的解决方案是从给定的列表中在 HashMap 下创建:
Map<Integer, Integer> numbersCountMap = new HashMap();
Run Code Online (Sandbox Code Playgroud)
其中键是列表中的值,值是出现次数。
然后循环遍历 HashMap 条目集,只要数字包含的计数大于 1,就从列表中删除该数字。
for (Map.Entry<Int, Int> numberCountEntry : numbersCountMap.entrySet()) {
if(numberCountEntry.getValue() > 1) {
testList.remove(numberCountEntry.getKey());
}
}
Run Code Online (Sandbox Code Playgroud)
我不确定这是否是解决此问题的有效方法,因为remove(Integer)对列表的操作可能很昂贵。此外,我正在创建额外的 Map 数据结构。并循环两次,一次在原始列表上创建地图,然后在地图上删除重复项。
你能不能提出一个更好的方法。可能是 Java 8 有更好的实现方式。我们还可以在 Java 8 中使用 Streams 和其他新结构在几行中完成吗?
我想创建将 Predicate::and 合并到一个谓词中的方法,并将其提交到输入列表中。我有代码:
public static List<?> getFilteredList(Collection<?> collection, Collection<Predicate<?>> filters) {
return collection.stream()
.filter(filters.stream().reduce(Predicate::and).orElse(t -> true))
.collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)
但是编译器说有一个错误 Predicate::and Incompatible types: Predicate<capture of ?> is not convertible to Predicate<? super capture of ?>
如何解决?
我正在尝试根据 Java 列表中的重复来获取前 N 个值。
示例:查找前 2 个值
[“草莓”、“橙子”、“苹果”、“芒果”、“葡萄”、“菠萝”、“芒果”、“草莓”、“芒果”、“苹果”]
结果:
["mango"] //mango 重复了 3 次
["strawberries", "apple"] // "strawberries", "apple" 各重复了 2 次
我写了下面的代码来实现这一点
private static List<List<String>> getTop(int n, List<String> values) {
Map<String, Long> valueCountMap = values.stream()
.collect(groupingBy(x -> x, counting()));
final Map<String, Long> sortedByCount = valueCountMap.entrySet()
.stream()
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> y, LinkedHashMap::new));
List<List<String>> topNValues = new ArrayList<>();
long prevValue = -1;
for (Map.Entry<String, Long> e : sortedByCount.entrySet()) {
if (prevValue == -1 || prevValue …Run Code Online (Sandbox Code Playgroud) 我正在使用 Java 流对某些数据执行一些转换。我想忽略地图中包含空值的任何值。
例子:
HashMap<String, Object> vals = new HashMap<>();
vals.put("null", null);
vals.put("string1", "1 ");
Run Code Online (Sandbox Code Playgroud)
我试过使用过滤器:
Map<String, Object> nullMap = vals.entrySet().stream()
.filter(e -> e.getValue() != null)
.collect(Collectors.toMap(
e -> e.getKey().trim(),
e -> (e.getValue() instanceof String ? ((String) e.getValue()).trim() : e.getValue())))
Run Code Online (Sandbox Code Playgroud)
但是,返回的对象完全删除了空键/值对(在我的示例中为“空”-> 空)。如何.filter在 Java 流中的步骤之后的任何后续处理过程中保留键“null”并忽略它?
在上面的例子中,我想得到一个返回的 Map ,其中键和值对被修剪,并且在修剪步骤中空值被“忽略”。
问题很简单:为什么我们不能在流中的操作中使用StringBuilder(...)as ,但可以用作?identity functionreduce(...)java8string1.concat(string2)identity function
string1.concat(string2)可以看作是相似的builder.append(string)(虽然可以理解为这些操作几乎没有区别),但是我无法理解reduce操作的区别。考虑以下示例:
List<String> list = Arrays.asList("1", "2", "3");
// Example using the string concatenation operation
System.out.println(list.stream().parallel()
.reduce("", (s1, s2) -> s1 + s2, (s1, s2)->s1 + s2));
// The same example, using the StringBuilder
System.out.println(list.stream() .parallel()
.reduce(new StringBuilder(""), (builder, s) -> builder
.append(s),(builder1, builder2) -> builder1
.append(builder2)));
// using the actual concat(...) method
System.out.println(list.stream().parallel()
.reduce("", (s1, s2) -> s1.concat(s2), (s1, s2)->s1.concat(s2)));
Run Code Online (Sandbox Code Playgroud)
这是执行上述行后的输出:
123
321321321321 // output when …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Java 8 流来创建一个 CarData 对象,该对象由列表中所有 CarData 字段的平均值组成getCars;
CarData = new CarData();
CarData.getBodyWeight returns Integer
CarData.getShellWeight returns Integer
Run Code Online (Sandbox Code Playgroud)
List<CarData> carData = carResults.getCars();
IntSummaryStatistics averageBodyWeight = carData.stream()
.mapToInt((x) -> x.getBodyWeight())
.summaryStatistics();
averageBodyWeight.getAverage();
IntSummaryStatistics averageShellWeight = carData.stream()
.mapToInt((x) -> x.getShellWeight())
.summaryStatistics();
getShellWeight.getAverage();
Run Code Online (Sandbox Code Playgroud)
我不想在我最终返回的结果中把这些都放在一起。
视觉上,这是我的清单
getCars() : [
{CarData: { getBodyWeight=10, getShellWeight=3 } }
{CarData: { getBodyWeight=6, getShellWeight=5 } }
{CarData: { getBodyWeight=8, getShellWeight=19 } }
]
Run Code Online (Sandbox Code Playgroud)
我试图实现的输出是一个对象,它具有我指定的每个字段的平均值。不确定我是否需要使用Collectors.averagingInt或 IntSummaryStatistics 的一些组合来实现这一点。对于这些技术中的任何一种,在一个字段中都可以轻松完成,只是不确定在使用多个整数字段时我缺少什么。
{CarData: { getBodyWeight=8, getShellWeight=9 } }
Run Code Online (Sandbox Code Playgroud) 我试图更好地理解 Java 中的流,我只是试图将嵌套的 for 循环表示为流,但我正在努力弄清楚。
我尝试了一些东西,但我似乎无法掌握它。
例如,这样的事情。
for (Profile profile : profiles) {
for (User user : users) {
if (user.getUserId().equals(profile.getProfileId())) {
profile.setField(false);
}
}
}
Run Code Online (Sandbox Code Playgroud)
作为 Java 中的流如何做到这一点?
我有一个我知道有n元素的数据源,我可以通过重复调用对象上的方法来访问它;为了举例,我们称之为myReader.find()。我想创建一个包含这些n元素的数据流。假设我不想调用该find()方法的次数超过我想返回的数据量,因为NoSuchElementException如果在到达数据末尾之后调用该方法,它将抛出异常(例如)。
我知道我可以通过使用该IntStream.range方法创建此流,并使用该方法映射每个元素find。但是,这感觉有点奇怪,因为我完全忽略了流中的 int 值(我实际上只是使用它来生成包含精确n元素的流)。
return IntStream.range(0, n).mapToObj(i -> myReader.read());
Run Code Online (Sandbox Code Playgroud)
我考虑过的一种方法是使用Stream.generate(supplier)后跟Stream.limit(maxSize). 根据我对limit功能的理解,这感觉应该可以工作。
Stream.generate(myReader::read).limit(n)
Run Code Online (Sandbox Code Playgroud)
但是,在 API 文档中没有任何地方表明该Stream.limit()方法将保证maxSize元素是由它所调用的流生成的。允许流实现n多次调用生成器函数并不是不可行的,只要最终结果只是第一次n调用,并且只要它符合 API 合约作为短路中间体手术。
返回由该流的元素组成的流,其长度被截断为不超过 maxSize。这是一个短路状态中间操作。
如果中间操作在呈现无限输入时可能因此产生有限流,则它是短路的。[...] 在管道中进行短路操作是无限流处理在有限时间内正常终止的必要条件,但不是充分条件。
Stream.generate(generator).limit(n)仅依赖于n调用底层生成器是否安全?如果是这样,是否有一些关于我遗漏的事实的文件?
并避免XY问题:什么是创造恰好执行操作流的惯用方式n倍?
我有一个像下面这样的 pojo 课程
public CategoryModel {
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个数组列表,如下所示。
List<CategoryModel> variantCategoryModelList = new ArrayList<>();
CategoryModel cat1= new CategoryModel();
cat1.setName(TEST1);
CategoryModel cat2= new CategoryModel();
cat2.setName(TEST1);
list.add(cat1);
list.add(cat2);
Run Code Online (Sandbox Code Playgroud)
我必须检查值“TEST1”和“TEST2”是否存在于列表中,如果两个值都存在于“列表”中,则返回“真”,我尝试了类似下面的方法,尽管我的“列表”同时具有值,它返回false。你能帮我检查一下我做错了什么顺便说一句我使用的是JDK 11。
final Optional<CategoryModel> optionalData = variantCategoryModelList.stream().
filter(valueData -> TEST1.equalsIgnoreCase(valueData.getName())
&& TEST2.equalsIgnoreCase(valueData.getName())).findFirst();
if(optionalData.isPresent()){
return true;
}
Run Code Online (Sandbox Code Playgroud) 我有以下 pojo:
class MyPojo {
String name;
int priority;
}
Run Code Online (Sandbox Code Playgroud)
我有一个List<MyPojo>. 现在,我想检索所有具有最高优先级的元素。这些元素的顺序无关紧要。
Java流可以做到这一点吗?我认为我应该首先按优先级分组,然后获取属于最高优先级的所有元素,但我不确定如何以有效的方式执行此操作。
java ×10
java-stream ×10
java-8 ×4
algorithm ×1
collections ×1
for-loop ×1
reduce ×1
sorting ×1