Find then replace/add using Java 8 [duplicate] - java-8

I am new to Java 8. I have a list of objects of class A, where structure of A is as follows:
class A {
int name,
boolean isActive
}
Now I have a list of elements L of class A, in that list I want to update an element having name="test" with inactive=false.
I can do this very easily by writing a for loop and creating a new list.
But how would I do that using Java 8 stream API?

You can do it like this.
L.stream()
.filter(item-> item.getName().equals("test"))
.forEachOrdered(a -> a.setActiv(false));
I believe data type of name should be String not int in your question

yourList.replaceAll(x -> {
if(x.getName().equals("SomeName")){
x.setIsActive(false);
return x;
}
return x;
})

Related

java 8 streams - Add two items in a list into a different item in the same list

I have a list with a custom class. I want to take the subSectionRank and the featureRank into the field rankingValue
I can do this with a loop but would like to be more efficient and use streams as the list is 400+
Here is the list
Here is the loop
public List<BaseFeatures> addFeatureRanking(List<BaseFeatures> baseFeatures){
for (int i = 0; i < baseFeatures.size(); i++) {
Integer subSectionRank = baseFeatures.get(i).getSubSectionRank();
Double featureRank = baseFeatures.get(i).getFeatureRank();
int ranking = (int) ((int)subSectionRank + featureRank);
baseFeatures.get(i).setRankingValue(ranking);
}
return baseFeatures;
}
Here is what i am trying.
List<Map.Entry<Double, Integer>> reducedAList = new ArrayList<>(baseFeatures.stream()
.collect(Collectors.groupingBy(BaseFeatures::getFeatureRank, Collectors.summingInt(BaseFeatures::getSubSectionRank)))
.entrySet());
I just dont know if i am on the right track or even remotely close. How can i use java 8 streams to accomplish what i am asking? Any heklp is much appreciated as java 8 streams is not my strong point.
It looks to me like all you want to do is the following:
where
BaseFeature is the class with the getters and setters
baseFeatures is the list of those classes.
for (BaseFeature bf : baseFeatures) {
bf.setRankingValue(bf.getFeatureRank() + bf.getsubSectionRank());
}
I'm not sure of the types so you may need to do some casting.

Updating an attribute of an element in list with matching attribute

I am new to Java 8. I have a list of objects of class A, where structure of A is as follows:
class A {
int name,
boolean isActive
}
Now I have a list of elements L of class A, in that list I want to update an element having name="test" with inactive=false.
I can do this very easily by writing a for loop and creating a new list.
But how would I do that using Java 8 stream API?
You can do it like this.
L.stream()
.filter(item-> item.getName().equals("test"))
.forEachOrdered(a -> a.setActiv(false));
I believe data type of name should be String not int in your question
yourList.replaceAll(x -> {
if(x.getName().equals("SomeName")){
x.setIsActive(false);
return x;
}
return x;
})

Java 8 stream compare two objects and run a function on them

I've a a stream which I want to partition into smaller parts based on matching Id and then apply some proccessing logic on each of the part/element.
class BigRequest{
String bId;
List<Parts> parts;
//getters and setter here
}
Class Parts{
String pId;
String partId;
//getters and setter here
}
I want to segregate and create a list of Parts of size 10 when the partId of different parts are same.
How to use the filter or reduce or groupingBy function to compare the two elements and put them to a list?
I've tried filter like below, doesn't take p1 variable:
big.stream().filter( p -> p.getPartId() == p1.getPartId()) //error
Tried groupingBy like this
big.stream().collect(Collectors.groupingBy(Parts::getPartId) //error
I want to iterate over the filtered/reduced list a another and call another function called abc(). How can I do it using Java Streams?
pseudo:
big.getParts().stream.
//dividing logic logic
for(i < parts.size)
abc(p)
Thanks
You might use something like this:
Map<String,List<Parts>> commonId = big.getParts().
stream().
collect(
Collectors.groupingBy(
Parts::getPartId,
Collectors.mapping(
Function.identity(),
Collectors.toList()
)
)
);
and after it, you will just need to iterate over the map and apply your function.
commonId.entrySet().stream().map(entry -> apply(entry))...
Updated
We can omit Collectors.mapping(Function.identity(),Collectors.toList()) part, since it is a default behaviour of groupingBy
Map<String,List<Parts>> commonId = big.getParts().
stream().
collect(
Collectors.groupingBy(
Parts::getPartId
)
);

Most efficient way to determine if there are any differences between specific properties of 2 lists of items?

In C# .NET 4.0, I am struggling to come up with the most efficient way to determine if the contents of 2 lists of items contain any differences.
I don't need to know what the differences are, just true/false whether the lists are different based on my criteria.
The 2 lists I am trying to compare contain FileInfo objects, and I want to compare only the FileInfo.Name and FileInfo.LastWriteTimeUtc properties of each item. All the FileInfo items are for files located in the same directory, so the FileInfo.Name values will be unique.
To summarize, I am looking for a single Boolean result for the following criteria:
Does ListA contain any items with FileInfo.Name not in ListB?
Does ListB contain any items with FileInfo.Name not in ListA?
For items with the same FileInfo.Name in both lists, are the FileInfo.LastWriteTimeUtc values different?
Thank you,
Kyle
I would use a custom IEqualityComparer<FileInfo> for this task:
public class FileNameAndLastWriteTimeUtcComparer : IEqualityComparer<FileInfo>
{
public bool Equals(FileInfo x, FileInfo y)
{
if(Object.ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
return x.FullName.Equals(y.FullName) && x.LastWriteTimeUtc.Equals(y.LastWriteTimeUtc);
}
public int GetHashCode(FileInfo fi)
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
hash = hash * 23 + fi.FullName.GetHashCode();
hash = hash * 23 + fi.LastWriteTimeUtc.GetHashCode();
return hash;
}
}
}
Now you can use a HashSet<FileInfo> with this comparer and HashSet<T>.SetEquals:
var comparer = new FileNameAndLastWriteTimeUtcComparer();
var uniqueFiles1 = new HashSet<FileInfo>(list1, comparer);
bool anyDifferences = !uniqueFiles1.SetEquals(list2);
Note that i've used FileInfo.FullName instead of Name since names aren't unqiue at all.
Sidenote: another advantage is that you can use this comparer for many LINQ methods like GroupBy, Except, Intersect or Distinct.
This is not the most efficient way (probably ranks a 4 out of 5 in the quick-and-dirty category):
var comparableListA = ListA.Select(a =>
new { Name = a.Name, LastWrite = a.LastWriteTimeUtc, Object = a});
var comparableListB = ListB.Select(b =>
new { Name = b.Name, LastWrite = b.LastWriteTimeUtc, Object = b});
var diffList = comparableListA.Except(comparableListB);
var youHaveDiff = diffList.Any();
Explanation:
Anonymous classes are compared by property values, which is what you're looking to do, which led to my thinking of doing a LINQ projection along those lines.
P.S.
You should double check the syntax, I just rattled this off without the compiler.

How do I use LINQ to obtain a unique list of properties from a list of objects?

I'm trying to use LINQ to return a list of ids given a list of objects where the id is a property. I'd like to be able to do this without looping through each object and pulling out the unique ids that I find.
I have a list of objects of type MyClass and one of the properties of this class is an ID.
public class MyClass
{
public int ID { get; set; }
}
I want to write a LINQ query to return me a list of those Ids.
How do I do that, given an IList<MyClass> such that it returns an IEnumerable<int> of the ids?
I'm sure it must be possible to do it in one or two lines using LINQ rather than looping through each item in the MyClass list and adding the unique values into a list.
IEnumerable<int> ids = list.Select(x=>x.ID).Distinct();
Use the Distinct operator:
var idList = yourList.Select(x=> x.ID).Distinct();
Using straight LINQ, with the Distinct() extension:
var idList = (from x in yourList select x.ID).Distinct();
When taking Distinct, we have to cast into IEnumerable too. If the list is <T> model, it means you need to write code like this:
IEnumerable<T> ids = list.Select(x => x).Distinct();
int[] numbers = {1,2,3,4,5,3,6,4,7,8,9,1,0 };
var nonRepeats = (from n in numbers select n).Distinct();
foreach (var d in nonRepeats)
{
Response.Write(d);
}
Output
1234567890

Resources