我刚刚开始学习 Java 中的 Streams 和并行,我想知道为什么普通的 for 循环IntStream在向数组添加项时比并行花费的时间更少。
package parallel;
import java.util.stream.IntStream;
public class Parallel {
public static void main(String[] args) {
final int[] intArray = new int[100000];
long startTime = System.currentTimeMillis();
IntStream.range(0, 100000).parallel().forEach(i -> intArray[i]=i);
long endTime = System.currentTimeMillis();
System.out.println("Parallel time: " + (endTime-startTime));
final int[] intArray2 = new int[100000];
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
startTime = System.currentTimeMillis();
for(int i = 0; i < 100000; i++){
intArray2[i] = …Run Code Online (Sandbox Code Playgroud) 我正在对 java 8 流功能进行一些练习,因此想到将知识应用于将数字字符串转换为整数列表的问题
一个典型的测试看起来像
@Test
public void testGetListofIntegersFromString(){
List<Integer> result = getIntegers("123456780");
assertEquals(Arrays.asList(1,2,3,4,5,6,7,8,0),result);
}
Run Code Online (Sandbox Code Playgroud)
我写了下面的方法
List<Integer> getIntegers(String value) {
return IntStream.rangeClosed(0, value.length() - 1).map(i -> Integer.valueOf(value.substring(i,i+1))).collect(?????);
}
Run Code Online (Sandbox Code Playgroud)
我被困在使用哪个函数来获取我尝试过的整数列表collect(Collectors.toList())它给出了编译错误。
请建议我们是否可以按照不同的方法来解决这个问题。
这个问题与我不久前发布的另一个问题有关。
我已经找到了一种按照我想要的方式对数据进行分组的方法。但是因为我需要对对象进行分组/映射,所以当我需要应用一些过滤时,我已经在收集期间关闭了流。我有以下代码:
final Map<TeamDetails, List<Player>> teamDetailsPlayerListMap =
dbRows.stream().map(row -> mapDbRowToTeamPlayerPair(row))
.collect(Collectors.groupingBy(TeamPlayerPair::getKey,
Collectors.mapping(TeamPlayerPair::getValue, Collectors.toList())));
final List<Team> teams = teamDetailsPlayerListMap.entrySet().stream()
.map(teamPlayerList -> mapTeamPlayerListToTeam(teamPlayerList))
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是某些 dbRowsString的playerName. 我不想在收集之前过滤,就好像 aTeam没有播放器一样(例如,只有 1 db 行,播放器名称为空字符串),我仍然希望Team在最后的s列表中包含它。它只会有一个空的玩家列表。
有什么方法可以在收集过程中应用过滤器,以便不会将空字符串或空字符串添加到列表中???
我已经能够使用自定义收集器实现它,如下所示,但我只是想知道是否有办法在没有自定义收集器的情况下做到这一点???
Function<Player, Boolean> emptyPlayerNameFilter = new Function<Player, Boolean>() {
@Override
public Boolean apply(Player player) {
return player != null && player.getName() != null && !"".equals(player.getName());
}
};
final Map<TeamDetails, List<Player>> teamDetailsPlayerListMap =
dbRows.stream().map(row -> mapDbRowToTeamPlayerPair(row))
.collect(Collectors.groupingBy(TeamPlayerPair::getKey,
Collectors.mapping(TeamPlayerPair::getValue,
MyCollectors.toFilteredLinkedList(emptyPlayerNameFilter))));
final List<Team> …Run Code Online (Sandbox Code Playgroud) 正如我List的主题
"Subjects":[
{"subject":"Math","grades":1},
{"subject":"Math","grades":2},
{"subject":"Math","grades":3},
{"subject":"Math","grades":3},
{"subject":"Lab","grades":10},
{"subject":"Lab","grades":12}
]
Run Code Online (Sandbox Code Playgroud)
我想这样分组并减少结果
//Expected Result
"Subjects":[
{"subject":"Math","grades":[1,2,3]},
{"subject":"Lab","grades":[10,12]}
]
Run Code Online (Sandbox Code Playgroud)
我很好奇如何映射和减少java8风格的对象。我在下面放置了过时的代码。
我的主班
public static void main(String[] args) {
List<Subject> list = new ArrayList<>();
list.add(new Subject("Math",1));
list.add(new Subject("Math",2));
list.add(new Subject("Math",3));
list.add(new Subject("Math",3));
list.add(new Subject("Lab",10));
list.add(new Subject("Lab",12));
Map<String, Set<Integer>> result = new HashMap<>();
list.stream().forEach(subjects-> {
if(result.get(subjects.getSubject())==null){
Set<Integer> set = new HashSet<>();
set.add(subjects.getGrades());
result.put(subjects.getSubject(),set );
}else{
Set<Integer> set =result.get(subjects.getSubject());
set.add(subjects.getGrades());
result.put(subjects.getSubject(), set);
}
});
result.forEach((key,val)->{
System.out.println("KEY:"+key + " RESULT :"+val);
});
}
public class Subject …Run Code Online (Sandbox Code Playgroud) 以给定的字符串为例:例如,My name is James Bond iee我想要Map将以character为键,将字符串集作为值(该字符串集是从相应字符键开头的字符串)- Map<Character,Set<String>>。例如:
m - my, n - name, i - is, iee, j - james etc.
我已经从标点符号和用于查找字符的书面方法中清除了字符串。在我的示例中:(m,n,u,j,b)
这些方法:
static String getPurifiedSentenceFromPunctuationMarks(String sentence) {
return sentence.replaceAll("\\p{P}", "");
}
static Set<Character> getEveryCharacterOccuringInSentence(String sentence) {
return sentence.chars()
.mapToObj(e -> (char) e).collect(Collectors.toSet());
}
Run Code Online (Sandbox Code Playgroud)
现在,我想遍历每个字符和每个字符串以找到这些单词,但是我在为每个字符创建集合方面感到挣扎:
String purifiedSentenceFromPunctuationMarks = AP.getPurifiedSentenceFromPunctuationMarks(sentence);
Set<Character> characters = AP.getEveryCharacterOccuringInSentence(purifiedSentenceFromPunctuationMarks);
String[] words = purifiedSentenceFromPunctuationMarks.split("\\s");
Map<Character, Set<String>> characterWithAccordingWord = new LinkedHashMap<>();
Set<String> nonRepeatableWords = new HashSet<>();
for (char iteratedCharacter : characters) { …Run Code Online (Sandbox Code Playgroud) 如果我这样做,性能或其他方面是否有差异?
list.stream().noneMatch(...)!list.stream().anyMatch(...)通常,在进行迭代时进行修改会立即引发ConcurrentModificationException。
但是,使用流API的forEachOrdered方法,每次修改后都不会引发Exception。取而代之的是,修改可以在迭代过程中成功进行,并且最终在整个操作完成后会引发异常。有人可以告诉我这是怎么发生的吗?
下面的代码生成3个随机数,范围从-0.5到0.5。然后过滤掉负值。
HashMap<Integer, Double> positiveNegative = new HashMap<>();
for (int i = 0; i < 3; i++) {
double value =Math.random() - 0.5;
positiveNegative.put(i, value);
}
System.out.println(positiveNegative);
//filter out the negative value
positiveNegative.entrySet().stream()
.filter((entry) -> (entry.getValue() < 0))
.forEachOrdered(entry -> {
System.out.println(entry);
positiveNegative.remove(entry.getKey());
System.out.println(positiveNegative);
});
System.out.println(positiveNegative);
Run Code Online (Sandbox Code Playgroud)
{0=-0.38785299800912576, 1=-0.11085161629013052, 2=-0.3516129030809366}
0=-0.38785299800912576
{1=-0.11085161629013052, 2=-0.3516129030809366}
1=-0.11085161629013052
{2=-0.3516129030809366}
2=-0.3516129030809366
{}
Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1751)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEachOrdered(ReferencePipeline.java:502)
at Solution.main(Solution.java:51)
Run Code Online (Sandbox Code Playgroud) 我内部ArrayList有一个有限数量的对象。我想在列表中查找字段中的特定值,然后进行更改。
我有以下实现。
String searchName = searchedName; //from outside we provide this
Person person = personList.stream()
.filter(personList -> searchName.equals(personList.getName()))
.findFirst()
.orElse(null);
if (person != null){
person.setName(replacement);
}
Run Code Online (Sandbox Code Playgroud)
这段代码可以工作,但是流不是我的专长,我的问题是:我是否可以具有相同的行为,而不必付出额外的代价呢?我觉得“如果”是多余的东西,我想使我的代码更有效。
附带的问题是,如果我们有多个具有相同名称的条目,则有一种使用流的方法,因此,除了“ .findFirst().orElse(null)”之外,我还可以使用哪种方法将其存储在person对象或可能的new对象中对象数组。
我有一些使用Arrays.stream(int arr [])。sum()添加的整数。它以int返回截断后的总和,而实际总和更大且适合long。为什么流API会通过截断而只返回int而不返回长整数?
尝试使用小整数,例如int myArray [] = {1,5,8}; int sum = Arrays.stream(myArray).sum();
工作正常。
但不适用于其和导致long的更长整数。
下面的情况1可以正常工作并返回14
int myArray[] = { 1, 5, 8 };
int sum = Arrays.stream(myArray).sum();
Run Code Online (Sandbox Code Playgroud)
而方案2无法使用,因为总和超过32位。它给出的总和为-105032716,而预期值为4189934580
int myArray[] = { 2094967290, 2094967290};
int sum = Arrays.stream(myArray).sum();
Run Code Online (Sandbox Code Playgroud)
并获得正确的总和,如果我在下面进行操作,则会得到预期的结果4189934580
long sum = 0L + 2094967290+2094967290;
System.out.println(sum);
Run Code Online (Sandbox Code Playgroud) 我有Integres列表,并希望从列表到地图获取最小值,最大值和平均值。下面是我的代码,
List<Integer> numbers = Arrays.asList(-2, 1, 2, 3, 5, 6, 7, 8, 9, 10, 100);
int min = numbers.stream().mapToInt(n -> n).min().getAsInt();
int max = numbers.stream().mapToInt(n->n).max().getAsInt();
double avg = numbers.stream().mapToInt(n->n).average().getAsDouble();
Map<String, Number> result = new HashMap<>();
result.put(“min”, min);
result.put(“max”, max);
result.put(“avg”, avg);
Run Code Online (Sandbox Code Playgroud)
但是我想要在Stream迭代中得到它,
numbers.stream().mapToInt(n->n).collect(toMap/* Map with min, max and average*/ ));
Run Code Online (Sandbox Code Playgroud)
有什么办法可以做到这一点?
java-stream ×10
java ×8
java-8 ×7
lambda ×2
arraylist ×1
benchmarking ×1
collectors ×1
object ×1
set ×1