ArrayLists and returning null - java

I'm trying finish my method 'priority' which should return the priority of the Task. and make it return null if the specified name does not exist (as shown in the main). I've tried iterating through the ArrayList, but i don't think this is the way to do it. Is there anyone who can help me out?
class Task
{
public static final ArrayList<Task> ALL_TASKS = new ArrayList<>();
private String name;
private Integer priority;
public Task(String name, Integer priority)
{
this.name = name;
this.priority = priority;
ALL_TASKS.add(this);
}
#Override public String toString()
{
return "name: " + this.name + "\tpriority: " + this.priority;
}
}
class Main
{
public static void main(String[] arguments)
{
new Task("Clean", 5);
new Task("Dishwash", 4);
new Task("Study", 1);
System.out.println(Task.priority("Dishwash"));
System.out.println(Task.priority("Vacuumclean"));
}
}

Try this:
public static Integer priority(String name) {
for(Task task : ALL_TASKS) {
if(task.name.equals(name)) {
return task.priority;
}
}
return null;
}
Or using Stream-API:
public static Integer priority(String name) {
return ALL_TASKS.stream()
.filter(task -> task.name.equals(name))
.map(task -> task.priority)
.findFirst()
.orElse(null);
}

public static Integer priority(String name) {
for(int i = 0; i < ALL_TASKS.size(); i++){
if(ALL_TASKS.get(i).getName().equals(name))
return ALL_TASKS.get(i).getPriority();
else
return null; // but if using Java 8 Option<Task> would be better
}
}
This is the example which I would use. It is not tested but it give you idea what create and the way of thinking.
Also in my solution I assume you also create getName() and getPriority() methods for your Task

The Java Stream API provides a more convenient and efficient approach to iterating and processing elements of a collection.
class Task
{
public static final ArrayList<Task> ALL_TASKS = new ArrayList<>();
public static Integer priority(String name)
{
List<Task> result = ALL_TASKS.stream().filter(task->
(task.name.equals(name))).collect(Collectors.toList());
if(result.isEmpty())
{
return null;
}
else
{
return result.get(0).priority;
}
}
private String name;
private Integer priority;
public Task(String name, Integer priority)
{
ALL_TASKS.add(this);
this.name = name;
this.priority = priority;
}
public String toString()
{
return "name: " + this.name + "\tpriority: " + this.priority;
}
}
class Main
{
public static void main(String[] arguments)
{
new Task("Clean", 5);
new Task("Dishwash", 4);
new Task("Study", 1);
System.out.println(Task.priority("Dishwash"));
System.out.println(Task.priority("Vacuumclean"));
}
}

An option would be storing your List as a Map instead, using the tasks name as the key
HashMap<String, Task> ALL_TASKS = new HashMap<>();
Task task = ALL_TASKS.get(codeIsIn);
if(task!=null)
{
Integer priority = task.priority;
}
If a Task consists only of name and priority, it gets even simpler
HashMap<String, Integer> ALL_TASKS = new HashMap<>();
Integer priority = ALL_TASKS.get(codeIsIn);
//null if nonexistent

Related

ArrayList occurance of object type

I have a class of orders and I want to see how many times a unique customerNumber will get mapped to a status reading "On Hold"
public class Orders {
private String status = null;
private int customerNumber = 0;
public Orders(String status, int customerNumber) {
super();
this.status = status;
this.customerNumber = customerNumber;
}
}
public int NumberOfOrdersOnHold(List<Orders> orders) {
int sum = 0;
for (Orders o : orders) {
if(o.getStatus().contentEquals("On Hold"));
}
}
I was thinking a counter method would work but it wouldnt. how will i achieve this method.I need numbers of orders in hold for each customerNumber not the total number.
Do it as follows:
import java.util.List;
enum OrderStatus {
ONHOLD("On Hold"), APPROVED("Approved"), DELIVERED("Delivered");
private final String statusCode;
private OrderStatus(String statusCode) {
this.statusCode = statusCode;
}
}
class Order {
private OrderStatus status = null;
private int customerNumber = 0;
public Order(OrderStatus status, int customerNumber) {
this.status = status;
this.customerNumber = customerNumber;
}
public OrderStatus getStatus() {
return status;
}
public void setStatus(OrderStatus status) {
this.status = status;
}
public int getCustomerNumber() {
return customerNumber;
}
public void setCustomerNumber(int customerNumber) {
this.customerNumber = customerNumber;
}
#Override
public String toString() {
return "Order [status=" + status + ", customerNumber=" + customerNumber + "]";
}
}
public class Main {
public static void main(String[] args) {
List<Order> orders = List.of(new Order(OrderStatus.ONHOLD, 1234), new Order(OrderStatus.APPROVED, 1234),
new Order(OrderStatus.ONHOLD, 2345), new Order(OrderStatus.APPROVED, 1234),
new Order(OrderStatus.ONHOLD, 1234), new Order(OrderStatus.ONHOLD, 2345));
System.out.println("Customer#1234 has " + numberOfOrdersOnHold(orders, 1234) + " order(s) on hold");
}
static int numberOfOrdersOnHold(List<Order> orders, int customerNumber) {
int count = 0;
for (Order order : orders) {
if (order.getCustomerNumber() == customerNumber && order.getStatus() == OrderStatus.ONHOLD) {
count++;
}
}
return count;
}
}
Output:
Customer#1234 has 2 order(s) on hold
Notes:
Use enum for status values as it makes easy for you to write and maintain the code. Check this to learn more about Java enum.
Follow Java naming conventions e.g. NumberOfOrdersOnHold should be named as numberOfOrdersOnHold.
The function, numberOfOrdersOnHold also requires the customer number whose order status has to be found.
You can use a Map! Try something like this:
public Map<Integer, Integer> numberOfOrdersOnHold(List<Orders> orders) {
final Map<Integer, Integer> map = new HashMap<>();
for (Orders o : orders) {
int currentNumber = o.getCustomerNumber();
// if map doesn't contain the key to the corresponding customer, were gonna add it
if (!map.containsKey(currentNumber)) {
map.put(currentNumber, 0);
}
// if the status is "On hold", increment the counter to the current customer
if ("On hold".equals(o.getStatus())) {
map.put(currentNumber, map.get(currentNumber) + 1);
}
}
return map;
}

How to create a list by iterating two different type of list, using java lambda expressions?

How can i change following code using java 8 lambda expressions. Below is my code:
public class Main {
class Student {
String name;
int mark;
String parentName;
public String getName() {
return name;
}
public int getMark() {
return mark;
}
public String getParentName() {
return parentName;
}
}
class Empl {
String name;
long salary;
String managerName;
public String getName() {
return name;
}
public long getSalary() {
return salary;
}
public String getManagerName() {
return managerName;
}
}
public static void main(String[] args) {
List<Student> list1 = new ArrayList<>();
List<Empl> list2 = new ArrayList<>();
// Storing data to list1 and list2
List<String> result = new ArrayList<>();
for(Student s :list1) {
result.add(s.getName());
result.add(s.getParentName());
}
for(Empl m :list2) {
result.add(m.getName());
result.add(m.getManagerName());
}
System.out.println(result);
}
}
In the above code i have used for loops for adding elements from two different lists. How can i use lamba expressions to perform the same steps above?
The following code does the same:
List<String> result = Stream.concat(
list1.stream().flatMap(s -> Stream.of(s.getName(), s.getParentName())),
list2.stream().flatMap(m -> Stream.of(m.getName(), m.getManagerName()))
)
.collect(Collectors.toList());
If you need to make sure that an ArrayList is created just use Collectors.toCollection(ArrayList::new) instead.
I'm not quite sure, but is this what you're looking for?
list1.forEach(s -> {
result.add(s.getName());
result.add(s.getParentName());
});
list2.forEach(m -> {
result.add(m.getName());
result.add(m.getManagerName());
});

Java8 Collecting data from 2 different object streams to a sorted list of 3rd object

So here's the problem. I have three classes as below:
class ObjectClassA
{
private final long id;
private final String name;
private final boolean isReadOnly;
//<some more fields>
long getId()
{
return this.id;
}
String getName()
{
return this.name;
}
boolean isReadOnly()
{
return this.isReadOnly;
}
}
class ObjectClassB
{
private final long id;
private final String location;
private final boolean isReadOnly;
//<some more fields>
long getId()
{
return this.id;
}
String getLocation()
{
return this.location;
}
boolean isReadOnly()
{
return this.isReadOnly;
}
}
and
class ObjectClassC
{
private final String location;
private final boolean isReadOnly;
private final String location;
String getName()
{
return this.name;
}
boolean isReadOnly()
{
return this.isReadOnly;
}
String getLocation()
{
return this.location;
}
}
I have 2 maps -
Map<Id,ObjectClassA> mapObjectClassA
and
Map<Id,ObjectClassB> mapObjectClassB
Both these maps are of the same size. The Id keys are common to both maps. The aim is to iterate over either maps to create a sorted (by ObjectClassC.name) List<ObjectClassC> objects such that:
ObjectClassC.name = ObjectClassA.name
ObjectClassC.isReadOnly = ObjectClassA.isReadOnly || ObjectClassB.isReadOnly
ObjectClassC.location = ObjectClassB.location
This is the logic that I have right now is as follows:
final List<ObjectClassC> list =
mapObjectClassA.values()
.stream()
.map(a -> {
new ObjectClassC(a.getName(),
a.isReadOnly() || mapObjectClassB.get(a.getId).isReadOnly(),
mapObjectClassB.get(a.getId).getLocation())
})
.sorted(Comparator.comparing(ObjectClassC::getName))
.collect(Collectors.<ObjectClassC> toList());
My mapping and collection are working fine, but I don't get a sorted collection of ObjectClassC objects. Could someone please point out where I'm going wrong?
Not so nice, but works.
public class MapMerge_38837365 {
public static void main(String[] args) {
Map<Integer, A> as = new HashMap();
as.put(1, new A("Anna"));
as.put(2, new A("Maria"));
as.put(3, new A("Eva"));
Map<Integer, B> bs = new HashMap();
bs.put(1, new B("Adam"));
bs.put(2, new B("Edward"));
bs.put(3, new B("Jon"));
Stream.concat(
as.entrySet().stream(),
bs.entrySet().stream()
).collect(Collectors.groupingBy(Map.Entry::getKey))
.entrySet().stream()
.map(e -> e.getValue())
.map(e -> {
if (e.get(0).getValue() instanceof A)
return new AB((A) e.get(0).getValue(), (B) e.get(1).getValue());
return new AB((A) e.get(1).getValue(), (B) e.get(0).getValue());
})
.map(ab -> new C(ab.a.name+" " +ab.b.name))
.forEach(System.out::println);
}
}
"The high magic" happens in Stream.concat then groupingBy. In this two lines we create stream of all entries from both maps. Then we group them by key to map. Elements with the same key (id) will go to one List<Object>. Next step is create new stream from grouping map entrySet().stream().
Then we extract value - entries with the same Id > map(e -> e.getValue()).
Next step is to build AB objects and could be omitted but I want to extract type check and cast to another function. Now we have pseudo pair AB, that is very nice candidate for create C class map(ab -> new C(ab.a.name+" " +ab.b.name)).
Classes A, B, C and AB:
class A {
final String name;
A(String name) {
this.name = name;
}
#Override
public String toString() {
return "A{" +
"name='" + name + '\'' +
'}';
}
}
class B {
final String name;
B(String name) {
this.name = name;
}
#Override
public String toString() {
return "B{" +
"name='" + name + '\'' +
'}';
}
}
class C {
final String name;
C(String name) {
this.name = name;
}
#Override
public String toString() {
return "C{" +
"name='" + name + '\'' +
'}';
}
}
class AB {
final A a;
final B b;
AB(A a, B b) {
this.a = a;
this.b = b;
}
#Override
public String toString() {
return "AB{" +
"a=" + a +
", b=" + b +
'}';
}
}

Setter for a key value pair List object

I am stumped with this one and hoping to see if this could be a good way to solve my issue.
I'll first explain how the program works.
I have a class that is simply a key value pair:
public class KeyValuePair {
private final String name;
private final String value;
public KeyValuePair(String n, String v) {
name = n;
value = v;
}
I have another class called List that uses the key value pair.
public class myList {
private List<KeyValuePair> myList = new ArrayList<KeyValuePair>();
public myList(List<KeyValuePair> nvp) {
List = nvp;
}
public List<KeyValuePair> getList() {
return myList;
}
}
So in my program i then create an List object and populate it with the key value pairs and review a new List(kvp).
public myList pullData(){
Final myList<KeyValuePair> nvp = new ArrayList<KeyValuePair>();
List<String[]> results = getResults()
for(String[] str : results)
{
KeyValuePair kvp = new KeyValuePair(str[0], str[1]);
nvp.add(kvp)
}
}
return new myList(nvp)
}
now I have run into the situation where I need to update the value of each pair. The key stays the same.
Originally I had created a newList object and populated with the updated Value for the key pair, but then though there should be a better method, perhaps creating an update or a setter method within the List object to do this.
Which would be better creating a new object, or updating? I would think updating the value in the key value pair, however, I am not sure how to do this.
Any help or suggestions would be greatly appreciated.
Then you can set the keys and values if you want:
public class KeyValuePair {
private String name;
private String value;
public KeyValuePair(String n, String v) {
name = n;
value = v;
}
public String getName(){
return name;
}
public String getValue(){
return value;
}
public void setName(String n){
name = n;
}
public void setValue(String v){
value = v;
}
}
However a list of these is never going to be as useful as a map that is already there in Java.
Lose final modifier and create nice getters and setters for your fields
public class KeyValuePair {
private String name;
private String value;
public KeyValuePair(String n, String v) {
name = n;
value = v;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
and then you can e.g. add plus sign to your values:
public void update(List<KeyValuePair> pairs) {
for (KeyValuePair kvp: pairs) {
kvp.setValue(kvp.getValue() + "+");
}
}
Simply by adding a setter to my key value pair class resolved this issue. Not too sure why i didn't see that before, for some reason I thought I needed to do it in myList class.
public void setValue (String newValue){
value = newValue;
}

Java getting the Enum name given the Enum Value

How can I get the name of a Java Enum type given its value?
I have the following code which works for a particular Enum type, can I make it more generic?
public enum Category {
APPLE("3"),
ORANGE("1"),
private final String identifier;
private Category(String identifier) {
this.identifier = identifier;
}
public String toString() {
return identifier;
}
public static String getEnumNameForValue(Object value){
Category[] values = Category.values();
String enumValue = null;
for(Category eachValue : values) {
enumValue = eachValue.toString();
if (enumValue.equalsIgnoreCase(value)) {
return eachValue.name();
}
}
return enumValue;
}
}
You should replace your getEnumNameForValue by a call to the name() method.
Try below code
public enum SalaryHeadMasterEnum {
BASIC_PAY("basic pay"),
MEDICAL_ALLOWANCE("Medical Allowance");
private String name;
private SalaryHeadMasterEnum(String stringVal) {
name=stringVal;
}
public String toString(){
return name;
}
public static String getEnumByString(String code){
for(SalaryHeadMasterEnum e : SalaryHeadMasterEnum.values()){
if(e.name.equals(code)) return e.name();
}
return null;
}
}
Now you can use below code to retrieve the Enum by Value
SalaryHeadMasterEnum.getEnumByString("Basic Pay")
Use Below code to get ENUM as String
SalaryHeadMasterEnum.BASIC_PAY.name()
Use below code to get string Value for enum
SalaryHeadMasterEnum.BASIC_PAY.toString()
Try, the following code..
#Override
public String toString() {
return this.name();
}
Here is the below code, it will return the Enum name from Enum value.
public enum Test {
PLUS("Plus One"), MINUS("MinusTwo"), TIMES("MultiplyByFour"), DIVIDE(
"DivideByZero");
private String operationName;
private Test(final String operationName) {
setOperationName(operationName);
}
public String getOperationName() {
return operationName;
}
public void setOperationName(final String operationName) {
this.operationName = operationName;
}
public static Test getOperationName(final String operationName) {
for (Test oprname : Test.values()) {
if (operationName.equals(oprname.toString())) {
return oprname;
}
}
return null;
}
#Override
public String toString() {
return operationName;
}
}
public class Main {
public static void main(String[] args) {
Test test = Test.getOperationName("Plus One");
switch (test) {
case PLUS:
System.out.println("Plus.....");
break;
case MINUS:
System.out.println("Minus.....");
break;
default:
System.out.println("Nothing..");
break;
}
}
}
In such cases, you can convert the values of enum to a List and stream through it.
Something like below examples. I would recommend using filter().
Using ForEach:
List<Category> category = Arrays.asList(Category.values());
category.stream().forEach(eachCategory -> {
if(eachCategory.toString().equals("3")){
String name = eachCategory.name();
}
});
Or, using Filter:
When you want to find with code:
List<Category> categoryList = Arrays.asList(Category.values());
Category category = categoryList.stream().filter(eachCategory -> eachCategory.toString().equals("3")).findAny().orElse(null);
System.out.println(category.toString() + " " + category.name());
When you want to find with name:
List<Category> categoryList = Arrays.asList(Category.values());
Category category = categoryList.stream().filter(eachCategory -> eachCategory.name().equals("Apple")).findAny().orElse(null);
System.out.println(category.toString() + " " + category.name());
Hope it helps! I know this is a very old post, but someone can get help.
I believe it's better to provide the required method in the enum itself. This is how I fetch Enum Name for a given value. This works for CONSTANT("value") type of enums.
public enum WalletType {
UPI("upi-paymode"),
PAYTM("paytm-paymode"),
GPAY("google-pay");
private String walletType;
WalletType(String walletType) {
this.walletType = walletType;
}
public String getWalletType() {
return walletTypeValue;
}
public WalletType getByValue(String value) {
return Arrays.stream(WalletType.values()).filter(wallet -> wallet.getWalletType().equalsIgnoreCase(value)).findFirst().get();
}
}
e.g. WalletType.getByValue("google-pay").name()
this will give you - GPAY
enum MyEnum {
ENUM_A("A"),
ENUM_B("B");
private String name;
private static final Map<String,MyEnum> unmodifiableMap;
MyEnum (String name) {
this.name = name;
}
public String getName() {
return this.name;
}
static {
Map<String,MyEnum> map = new ConcurrentHashMap<String, MyEnum>();
for (MyEnum instance : MyEnum.values()) {
map.put(instance.getName().toLowerCase(),instance);
}
unmodifiableMap = Collections.unmodifiableMap(map);
}
public static MyEnum get (String name) {
return unmodifiableMap.get(name.toLowerCase());
}
}
Now you can use below code to retrieve the Enum by Value
MyEnum.get("A");

Categories